wiring and reading a rotary (BCD) switch - HOW?

I am just getting started with the whole Arduino world with a project that I'm hoping will make my life a little better... I am a paraplegic due to a spinal cord injury, and since my feet don't work anymore, I'm trying to build an "electric pedal pusher" to work with machines that use foot-pedals for control, such as TIG welders and sewing machines for instance.

Eventually I will be (hopefully) controlling it with an EZ-VR speech reco shield, which may be the cause for other questions later, but for the moment....

Different machines have different operating approaches when it comes to how one pushes the pedal - a TIG machine wants the pedal floored rapidly at start, and then ease off as the puddle develops. OTOH a sewing machine usually wants you to sort of ease into it. There are also devices that have a "binary" on/off pedal - I think it's desirable to have the pusher be able to have different "profiles" as to how it behaves depending on what it's being used with.

To do this, I have a rotary 0-9 "Binary Coded Decimal" switch - it has four outputs, one for each bit (1,2,4,8) and a common. I am trying to figure out both how to wire it, and how to write the appropriate code for it. I've done quite a bit of searching, and haven't really found anything specific...

I am going to have plenty of I/O pins available to me, and it seems to me like the simplest approach is to plug the switch outputs to digital I/O pins (presumably D2-D5) and the common to either +5 or ground. Assuming I'll be using the internal pull-up resistors, does the common go to ground? Is there a better way to wire it?

My working assumption is that the pusher will be powered down when switching pedals, and that selecting the "profile" will be done as part of the hardware setup, and will not change while the pusher is in use....

Therefore I want to read the switch setting, and store it in a variable (call it "profile") as early in the "void setup() {" part of the sketch as possible, and then use that value with a "switch" or nested loop set in both the rest of the setup and in the loop to adjust the function of the different speech reco commands....

How do I read the switch and get it into a single (decimal) value (I think it will be an "int" as the range will only be 0-9)

To give a rough idea of what I'm trying - here's some bad pseudo-code....

SETUP:
Read switch bits
Combine to intl variable "profile"

If profile = 1 case TIG
set TIG vocabulary
Start
Stop
up
down

if profile = 2 case Sewing machine
set sewing machine vocabulary
Start
Stop
up
down
....

If profile = 9 case binary pedal
set binary vocab
on
off

LOOP:

If profile = 1
Start - set pusher = 90%
Stop - set pusher = 0%
up - increase pusher 1%
down -decrease pusher 1%

If profile = 2
Start - set pusher 40%
Stop - set pusher 0%
up increase pusher 5%
up decrease pusher 5%

.....

If profile = 9
On - set pusher 100%
Off - set pusher 0%

Move servo to pusher position....

Thanks for either advice or pointers to links I may have missed...

ex-Gooserider

To do this, I have a rotary 0-9 "Binary Coded Decimal" switch - it has four outputs, one for each bit (1,2,4,8) and a common. I am trying to figure out both how to wire it, and how to write the appropriate code for it. I've done quite a bit of searching, and haven't really found anything specific...

I am going to have plenty of I/O pins available to me, and it seems to me like the simplest approach is to plug the switch outputs to digital I/O pins (presumably D2-D5) and the common to either +5 or ground. Assuming I'll be using the internal pull-up resistors, does the common go to ground? Is there a better way to wire it?

A simple and cheapest method to read a rotary BCD switch is to wire the common to ground and wire the 4 switch bits (8421) to 4 arduino input pins and then enable the optional internal pull-up resistors for those pins. The disadvantage of this method is that the data bit values will be inverted (on = ground = low = 0) and you will have to invert the bits in software if you wish to deal with true (on = +5vdc = high = 1) data.

To wire and use the switch in a true data manner, then the common would wire to +5vdc and again the four data bit switch contacts would wire to four arduino input pins and then you would then need to have four external pull-down resistors (10k ohms would work well) wired to each arduino input pin and ground.

If speed is ever an issue you could utilize arduino pins belonging to the same port and then use direct port access to read all the bits in one read operation Vs using arduino digitalRead() commands on each individual switch contact value. The main disadvantage of this technique is that the resulting code will not be portable between different chip types, like the Uno Vs Mega boards.

Good luck on your project.

Lefty

Many thanks for the advice... It was good to get me started.

I now have the switch wired, and basic code written to read the switch state one time during the initialization stage of the program. I also had it working with minor changes as a loop to read the value of the switch on each pass...

This is what I came up with - suggestions on how to improve it are welcome 8)

// TEST For "Profile switch" currently set to read BCD switch 
// once during setup; move code as noted below for repeated reads

// BCD Switch inputs attached to pins D2-5, common to Ground 
// (use internal pullups)

// Define data bit pins
    int      profile_BIT1  = 2;
    int      profile_BIT2  = 3;
    int      profile_BIT4  = 4;
    int      profile_BIT8  = 5;

// Define profile variable, set to 0

    int      profile = 0;

void setup() {
// initialize serial communication at 9600 bits per second (only needed
// for debugging:
  Serial.begin(9600);

// make the profile switch's pins inputs, with internal pullups on:
  pinMode(profile_BIT1, INPUT_PULLUP);
  pinMode(profile_BIT2, INPUT_PULLUP);
  pinMode(profile_BIT4, INPUT_PULLUP);
  pinMode(profile_BIT8, INPUT_PULLUP);
  
// to make read on each pass move all below this to "loop",  
// uncomment profile reset


// read the input pins: NOTE - CLOSED switch (binary 1) returns "0"
  int val_profile_BIT1 = digitalRead(profile_BIT1);
  int val_profile_BIT2 = digitalRead(profile_BIT2);
  int val_profile_BIT4 = digitalRead(profile_BIT4);
  int val_profile_BIT8 = digitalRead(profile_BIT8);



//int     profile =  0; needed in loop to reset to 0 for each pass

// turn bit values into single profile value by adding decimal value 
// of each bit to profile variable

if (  val_profile_BIT1 ==  0)    { profile = profile + 1; }
if (  val_profile_BIT2 ==  0)    { profile = profile + 2; }
if (  val_profile_BIT4 ==  0)    { profile = profile + 4; }
if (  val_profile_BIT8 ==  0)    { profile = profile + 8; }

// DEBUG - prints out the state of the switch bits and profile value

   {Serial.print("[profile_BIT1: ");
    Serial.print(val_profile_BIT1);
    Serial.print("] ");
    Serial.print("[profile_BIT2: ");
    Serial.print(val_profile_BIT2);
    Serial.print("] ");
    Serial.print("[profile_BIT4: ");
    Serial.print(val_profile_BIT4);
    Serial.print("] ");
    Serial.print("[profile_BIT8: ");
    Serial.print(val_profile_BIT8);
    Serial.print("] ");
    Serial.print("[profile: ");
    Serial.print(profile);
    Serial.println("] ");}
    
  }
  
// delay in between reads for stability, uncomment if in loop
//  delay(1000); 

  void loop() {
    
}

Looks great to me. Very readable code using straight forward statements that will be easy to read and understand even months and years later. One thing I sometimes do when writing something like this (to read that switch) is to rewrite it as a user function, that way it can be reused in other sketches.

Good luck

Lefty