Switch case statement for multiple digitalRead inputs?

Hey guys,

I have a question.

in arduino C, how would you go about having digital pin 14,15,16,17 as input? the control logic coming from a TX2 chip Forward/Rev/Left/Right outputs..

 

Thanks,

-Raff

 

 

 

 

 

 

After searching for more,

After searching for more, found this…

http://www.linksprite.com/product/showproduct.php?lang=en&id=184

 

 

Use Domain Specific Terms

You talk about pins. A pin is a very low level concept.

Could it be that your problem decomposition uses terms like distance, direction and speed ? If so then you could reflect that in your code. The more your domain specific terms are used in the code the more the code speaks to you.

Finding a switch with 0b00001111 as cases seems very odd (as it is shown in the example). Will you understand its meaning one week after writing? Having a switch statement that spans over several screen pages can overstrain our intellectual abilities. Will you understand this after a while?

There is nothing wrong using a binary bitmap but it can be hidden using variables with domain specific names.

Hey Nils,pardon my coding,

Hey Nils,

pardon my coding, still a n00bie…just needed a quick solution to my “slight” problem.

The code linked below, works OK since all the Analog inputs(A0-A7) are used as inputs. at the moment, Im just using A0-A3. there is a slight problem though, I can’t use A5 as output(for use on piezo buzzer)…just a quick solution to a problem :stuck_out_tongue: oh heck, need more learning.

 

 

unsigned char motion=0;

void setup()
{
 pinMode(A0,INPUT);
 pinMode(A1,INPUT);
 pinMode(A2,INPUT);
 pinMode(A3,INPUT);
 pinMode(A4,INPUT);

}

void loop()
{
  motion = digitalRead(A0) + digitalRead(A1)*2 + digitalRead(A2)*4 + digitalRead(A3)*8 + digitalRead(A4)*16;
 
  switch(motion)
  {
    case 0b00000001:  forward();        break;
    case 0b00000010:  backward();       break;
    case 0b00000100:  rotate_left();    break;
    case 0b00001000:  rotate_right();   break;
    case 0b00000101:  crab_left();      break;
    case 0b00001001:  crab_right();     break;
   
    default:  servoENABLE(); 
  }
}

 

What is the Meaning of A0?

That is fine. But what is the meaning of A0 for you? What “sense” is it? Why is the combination of A0 and A2 lead to crab-left?

You intensional hide information here and this can lead to code-horror since you loose the connections between the dots. The concept is hidden.

To stay explicit and intension revealing is always good. Especially if you are new to programming.

So show the concepts wherever you can. Your mind will thank you for that :wink:

Two things

Why are you using so many analog inputs for digital? And, what NilsB is saying is something one learns in programming courses. Make your variable names as explicit as possible. For example if you write a program to calculate sales tax on a dinner bill, you will have the sale, the tax, the subtotal, and the total at a minimum. Calling them n1, n2, n3, n4 will not help you down the road when you come back to look at the code.

I believe what he is saying is turn your binary constants/variables into named variables/constants, so, you can look at the code and not have to worry about wth does 0b00000100 mean again?

First of all, all pins are

First of all, all pins are in Input mode at start up. You only need to declare them Output if needed. Secondly, you can use any analog pins as output for anything, even if you use the other pins for input or for analog read. So yeah, you can declare A4 as output and use a piezo speaker on it. Remember, all the pins are I/O pins, some of them have additional functions that need to be declared to be used. Arduino IDE declares them when needed, except the Output mode that you have to do it yourself and the pull up resistors for the input mode.

** well ok here is the main**

 

well ok here is the main connections to the duino board (I use digital I/O pins 2-13 for the 12 servo connections, Im leaving digital I/O 0 and 1 for the rx/tx)… now I am left with using AO-A5(or digital I/O 13-19) for connection to an RX2 chip, those chips found on cheap R/C toys… they have 5 decoded outputs there, but I am using only 4 at the moment… A0=forward A1=reverse A2=left A3=right, A4=unused… so this means I will have an extra I/O here (A5) to use as OUTPUT… now im utilizing the A0-A5 as digital INPUTS, not analog… I have tried using if -else-if but my problem is if I press the forward, and press the left, the code will still do the “forward” function… that is why I use the switch case…I am still learning using this though…

about that binary constants into variables, can you show me how this can be done? I hope I made myself clear in my posts above… sorry If I cant explain much regarding code…

Getting more clear now…

Binary into constant… The easist way would be to simply use actual numbers instead of binary.

case 1:
break;
case 2:
break;
case 3:
break; 

Expanding on that, you could define these constants with names up at the top of your program:

#define want_to_go_forward 1
#define want_to_go_right 2

This would make it easier to read and understand your code

 

Now, in terms of watching for different buttons that are being hit. The problem is not because you are using IF’s or Case, it is the fact that you have not told the robot what to do when 2 buttons are being pushed. You are wicked close though. First off, you have assigned different values to each of your inputs so when they are added, you can figure out (with math) what has been hit. However, you don’t have a case for say, 17 --which is forward and crab right mixed together. Same with 5 --forward and rotate left mixed together. 

That’s really it. Just add some more cases so you have all the combinations of buttons covered. 

I should add

What I said above is only true based on what I am guessing is in your motor routine functions. For all I know, you could have something funny in there that is keeping your code locked up. If those routines are what I think they are --I.e., set the motor direction and return, then what I said above is true.

Yeah, I too think that Chris

Yeah, I too think that Chris if right although it if not necessary that you use #define to declare a global scope variable which is pre processed by the compiler (global scope variables exist throughout the life of the function ie until the batteries are pulled). You can follow my way our that of Chris. Both are correct.

Correction

The while loop method that I suggested above is a complete waste as I see that the loop() already does that.

ok i have abetter

ok i have abetter question.how would you go about getting the data from all the 4 digitalpins  and making it into one?

You have already done that

You have already done that with the statement motion= digitalRead(A0)+ digitalRead(A1)*2+ digitalRead(A2)*4+ digitalRead(A3)*8+ digitalRead(A4)*16; The problem is, as Chris says, that all the outputs are not mapped. When you press say A1 with A2, motion stores the value 6 which in binary is 0b00000110 which as I see from your above code is a case that has not been defined. For a successful coding, you should define all possible combinations no matter how unlikely they are to occur. You have defined outputs for the values 1 ,2,4,5,8,9 but not for values 3,6,7,10,11,12 etc. (convert to binary yourself). If you define all possible outcomes, your code won’t be bugged.

I had to look this up, but, I think it should work.

  switch(PINC)
  {
    case 0b00000001:  forward();        break;
    case 0b00000010:  backward();       break;
    case 0b00000100:  rotate_left();    break;
    case 0b00001000:  rotate_right();   break;
    case 0b00000101:  crab_left();      break;
    case 0b00001001:  crab_right();     break;
    
    default:  servoENABLE();  
  }

You might need to declare a variable and initialize it to PINC, but, it should work otherwise.

Realize that I am not fluent in arduino, nor do I have an arduino to play with.

The code you have given and

The code you have given and the code that he is using is no different. Changing the name of the variable doesn’t have any change. The compiler doesn’t care if you use PINC our motion (unless PINC is a KEYWORD) as your variable. What it cares about is the value stored in that variable (this should hold true if arduino is really based on C as it holds true in C). Define more outputs. And post the complete code. There might be some problem with the functions that you are using and not with the switch case.

Our there can also be some problem in the way you have wired your motors and servos

PINC

is indeed a keyword. It is meant to read the status/bits of PortC, which happens to be the 6(8) analog pins including the pins he is currently planning on reading.

I will agree that there doesn’t seem to be a reason to read things differently.

He asked. I answered.

oh my :slight_smile:

posts are getting Looooong already :slight_smile:

Guys, MY 1st post was that I was unsure as how I would make a switch case of multiple digitalinput/s (pin14-pin19 OR A0-A5)… in short, this would result to forward(); when a HIGH is detected on A0(pin14). or backward(); when a HIGH is read at A1(pin15) or rotate_left(); with a HIGH on A2(pin16) or a crabwalk_left(); with both a HIGH on A0 & A2… now my 2nd problem was my piezo would not play a tune… but its all fixxed now… I added

pinMode(19,OUTPUT);

inside void setup() … and NOW it is sounding off… I thought that calling tone(pin,freq); would just do the trick, but it did not…

the RX2 chip is a decoder so no need to decode signals coming from the transmitter. can be forward/backward/forward+left/forward+right/bacward+left/backward+right/turbo+left/turbo+right. every function. there is a certain pin that would output HIGH for forward, another pin for reverse, etc etc…

so what I would “get” from the RX2 chip is a “set” of lows and HIGHs…meaning RX2 has 5 pins for those “outputs”…Forward/Reverse/Left/Right/Turbo(seldom used)… for example, I get a 1000 for forward, 1(for A0), 0(for A1), 0(for A2), 0(for A3)… for the reverse, will be 0100, 0(for A0), 1(for A1), 0(for A2), 0(for A3)… .and for that crabwalk_left(), I should get a 1010 , 1(for A0), 0(for A1), 1(for A2) , 0(for A3)… whew :slight_smile: its an or/and function…

my problem is how I would write those digitalinputs for switch case? because samples I see are usually from serial data, or from just a single pin input (with 1 or 0 only)…

once again, my hardware is perferctly working with the above code/link I have posted/found on the net…maybe tomorrow I will post a video of it doing all those movements…

but 1 thing still remains, HOW do I code it RIGHT? :smiley:

I learn faster through actual code samples… goodnyt all! :slight_smile:

 

I found it on the net,

I found it on the net, copied, AND IT WORKED… thats what mattered the most… :smiley: I never did that … :smiley:

anways, the code works like a charm, my bot is up and “running” already… forward/reverse/rotate left & right, and crabwalk left & right with a combination of forward/left or forward/right… will post a video soon

My suggestion.

If the only place the binary numbers appear in your code is the set of case statements in your switch, add a comment before the switch detailing what each bit is connected to. Or, maybe a remark next to each case statement as to which pins are being called.

As to why you had to set your pin to output before you could use it, arduino defaults all pins as input. You must specifically call for pins to be set as outputs (I learned that through some of my reading to find the PINC command).