question on the logic/approach using a slide switch?(any position on power up)

For some reason.. I'm having a brain fart with wrapping my head around this... =(

I have a slide switch:
similar to this.. (but with only 3 legs instead of 6)

that I am using in a project...

it can set the 'project' to either semi-auto... or full-auto..

I have it playing a sound effect whenever it is toggled either way..

what Im having a problem with is... setting itup correctly I guess..

I currently just use an internal pull-up resistor for it, and have tried several attempts at the code for it..

its just that.. I'm a bit stumped with using an internal pull-up resistor.. but this slide switch can really be in any position upon start up..

after several attempts.. it either 'doesnt toggle' any more..

or 'always' plays the mode select audio file upon power-up (which I dont want)..

so Im unclear on how I can code/prepare for the slider the be in any position upon start up, still not having the switch be floating.. and NOT play the mode select audio file upon boot-up/power-up..

I hope that makes sense.. (kinda hard to explain)

thanks

const int modeSelect_btn =  2;

void setup() {  
  //pin2 mode select
  //pinMode(modeSelect_btn, INPUT);
  //digitalWrite(modeSelect_btn, HIGH); //no float
  pinMode(modeSelect_btn, INPUT_PULLUP);
  autoFire = digitalRead(modeSelect_btn);
  Serial.print("MODE SELECT CHECK: ");
  Serial.println(autoFire);  
}


void loop() {  
    //check the fire mode button state  
  if (digitalRead(modeSelect_btn) && autoFire == false) {
    //mode select audio notification       
    putstring_nl("mode select changed: auto");
    Serial.println(digitalRead(modeSelect_btn));
    playcomplete("amode.WAV"); 
    autoFire = true;
  }
  else if (!digitalRead(modeSelect_btn) && autoFire == true) {
    //mode select audio notification    
    putstring_nl("mode select changed: semi");
    Serial.println(digitalRead(modeSelect_btn));  
    playcomplete("smode.WAV");
    autoFire = false;  
  }
}

xl97:
For some reason.. I'm having a brain fart with wrapping my head around this... =(

I have a slide switch:
similar to this.. (but with only 3 legs instead of 6)
RadioShack.com Official Site - America's Technology Store

that I am using in a project...

it can set the 'project' to either semi-auto... or full-auto..

I have it playing a sound effect whenever it is toggled either way..

what Im having a problem with is... setting itup correctly I guess..

I currently just use an internal pull-up resistor for it, and have tried several attempts at the code for it..

its just that.. I'm a bit stumped with using an internal pull-up resistor.. but this slide switch can really be in any position upon start up..

after several attempts.. it either 'doesnt toggle' any more..

or 'always' plays the mode select audio file upon power-up (which I dont want)..

so Im unclear on how I can code/prepare for the slider the be in any position upon start up, still not having the switch be floating.. and NOT play the mode select audio file upon boot-up/power-up..

I hope that makes sense.. (kinda hard to explain)

thanks

It appears that you need something like this near the start of loop():

while(slideSwitch_not_moved){
check slideSwitch_setting;
} //do nothing until switch moved

so that it waits until the switch is toggled (at least once) before doing anything.

It would help if you posted some code that compiled.

sorry I'm at work.. and didnt want to not post ANYTHING..

I wanted to get the idea across..

here (not like it was major pobelms)

const int modeSelect_btn =  2;
boolean autoFire;

void setup() {  
  //pin2 mode select
  pinMode(modeSelect_btn, INPUT);
  digitalWrite(modeSelect_btn, HIGH); //no float
  //pinMode(modeSelect_btn, INPUT_PULLUP);
  autoFire = digitalRead(modeSelect_btn);
  Serial.print("MODE SELECT CHECK: ");
  Serial.println(autoFire);  
}


void loop() {  
    //check the fire mode button state  
  if (digitalRead(modeSelect_btn) && autoFire == false) {
    //mode select audio notification       
    Serial.println("mode select changed: auto");
    Serial.println(digitalRead(modeSelect_btn));
    //playcomplete("amode.WAV"); 
    autoFire = true;
  }
  else if (!digitalRead(modeSelect_btn) && autoFire == true) {
    //mode select audio notification    
    Serial.println("mode select changed: semi");
    Serial.println(digitalRead(modeSelect_btn));  
    //playcomplete("smode.WAV");
    autoFire = false;  
  }
}

@ Henry_Best -
thanks for the reply..

yeah something like that..

Im just confused,, two parts:

1.) if using internal pull-up resistor (to stop pin from floating)// that makes the PIN "HIGH"... so already (more or less) setting the select mode varibles..

2.) upon boot up.. the slider can be in ANY position (HIGH/LOW).. who knows if its in semi-auto mode.. or full-auto mode upon boot-up...

so if its LOW..upon boot....but then pulled-high with internal pul-up.. (or vise versa depending on order read/done)..
it toggles the value/variable without the switch being physically moved..

make sense? LOL

The symptoms suggest that you have not wired the switch up correctly. How is it wired?

hmm… you could be right… (I DID bump it out the breadboard, maybe I replaced it wrong?) (now you got me thinking!) lol…
or I could just have it wired up wrong to begin with?? <— probably more so the case… :slight_smile:

however…it wired as so: (I’ll double/triple check when I get home tonight though)
*internal pull-up enabled

pin 1 to Arduino pin

middle pin to GND rail

pin 3 (nothing)

how should I have it wired, knowing the above and what its use is for…etc… and that when powered up…it an be in any position.

thanks!

however..it wired as so: (I'll double/triple check when I get home tonight though)
*internal pull-up enabled

pin 1 to Arduino pin

middle pin to GND rail

That part should be right. Then, reading the pin should show LOW is the switch is in one position and HIGH in the other position. When you connect the third leg to another pin, that pin should read HIGH and LOW when the first pin reads LOW and HIGH.

Thanks for reply PaulS.

I'm not/wasnt planning on using the 3 leg on the switch.. needed?

So something in my code isnt correct then?

or Im confused (or both) still! LOL

in code.. I am setting pin HIGH (for pull-up resistor)

but I have no idea what state the slider is in..or will be in, on power-up..

So its set HIGH in code...

but I need to read the switch state in order to know if its in FULL-AUTO mode or SEMI-AUTO mode.. so the code/sketch acts accordingly..

if set HIGH with input-pull..etc..

and the switch is actually LOW when powered up... it plays the audio file/sound clip (which it shouldnt..it should never play the sound on boot-up..only when the switch is actually physically toggled)

I keep having a brain fart!.. I 'feel' like its an easy fix. .and the answer in front of my face with some silly code error/handling or something..

suggestions on a nice way to handle this? (Im sure latching/slider switch have been used by many people) :slight_smile:

if the 2 states of a latching switch, dictate two different events/paths in the code.....
and you dont know what state this button will be upon powering on.. but you use an internal pull-up to stop the pin from floating..

how to overcome this? (I'm keep waiting for the "DUH" moment)...

thanks!

In the first code you posted, you have the pinMode() setting INPUT_PULLUP commented out.

Is this still the case?

actually in the FIRST code.. it was NOT commented out..

but because it wouldnt compile..

(wasnt sure if poster had Arduino 1.0 or under or above)

I just edited it out to be HIGH in the second 'compilable' version of the code.

I tried old way (HIGH).. I tried new way (INPUT_PULLUP)..

but no difference.. (not that I thought there should be)..

like the initial suggestion.. Im left thinking that I need to set some sort of flag/variable to ignore the 'button' checkign until 1 manual toggle has been done or something..

:frowning:

Well, this is your code with a few things commented out. It works just fine. You might have the True/False reversed, but I'm not sure and I just got called away for a while.

const int modeSelect_btn =  2;
bool autoFire;

void setup() {  
  //pin2 mode select
  //pinMode(modeSelect_btn, INPUT);
  //digitalWrite(modeSelect_btn, HIGH); //no float
  pinMode(modeSelect_btn, INPUT_PULLUP);
  Serial.begin(19200);
  autoFire = digitalRead(modeSelect_btn);
  Serial.print("MODE SELECT CHECK: ");
  Serial.println(autoFire);  
}


void loop() {  
  //check the fire mode button state  
  if (digitalRead(modeSelect_btn) && autoFire == false) {
    //mode select audio notification       
    //putstring_nl("mode select changed: auto");
    Serial.print(digitalRead(modeSelect_btn));
    //playcomplete("amode.WAV"); 
    autoFire = true;
  }
  else if (!digitalRead(modeSelect_btn) && autoFire == true) {
   //mode select audio notification    
  //  putstring_nl("mode select changed: semi");
    Serial.print(digitalRead(modeSelect_btn));  
  //  playcomplete("smode.WAV");
    autoFire = false;  
  }
  Serial.print("  ");
  Serial.println(autoFire);
  delay (500);
}

I'm not/wasnt planning on using the 3 leg on the switch.. needed?

No.

but I have no idea what state the slider is in..or will be in, on power-up..

One side is either connected (pressed) or not (released). The fact that the switch is held, mechanically, instead of momentary contact is completely irrelevant.

but I need to read the switch state in order to know if its in FULL-AUTO mode or SEMI-AUTO mode.. so the code/sketch acts accordingly..

Those aren't switch states. The are program states, that you want to select based on the switch state (contact/pressed or no contact/released).

if set HIGH with input-pull..etc..

You enable the pullup resistor before reading the switch. Then, when you read the switch it is either pressed/slid to that side/LOW or released/slid to the other side/HIGH.

and the switch is actually LOW when powered up... it plays the audio file/sound clip (which it shouldnt..it should never play the sound on boot-up..only when the switch is actually physically toggled)

That's a completely separate requirement from pressed vs. released. What I hear you saying is that regardless of the position on start up, you want the switch to change to the non-pressed state and back again before you consider it pressed.

That means that you need a boolean variable to keep track of whether the switch has ever been read as HIGH. Set it whenever the switch is read as HIGH. Then, when the switch is LOW and the flag is true, do whatever you need (play the sound, etc.).

I keep having a brain fart!.. I 'feel' like its an easy fix. .and the answer in front of my face with some silly code error/handling or something..

I don't know about a brain fart, but I have the same feeling.

man.. I cant seem to grasp it??

You enable the pullup resistor before reading the switch. Then, when you read the switch it is either pressed/slid to that side/LOW or released/slid to the other side/HIGH.

I am doing this..(I think)
Im enabling pin as pull-up
-then- I read the switch..

//pin2 mode select
  pinMode(modeSelect_btn, INPUT_PULLUP);
  autoFire = digitalRead(modeSelect_btn);

That's a completely separate requirement from pressed vs. released. What I hear you saying is that regardless of the position on start up, you want the switch to change to the non-pressed state and back again before you consider it pressed.

hmm.. I guess I'm not following? I want the slide switch to dictate if the it does SEMI fire mode or AUTO fire mode.. so if the prop powers up..and the switch in LOW.. its does the SEMI fire events/code.... if the switch is in HIGH..it should do the AUTO fire events/code..
you'll never know what position the switch is in when it powers up.. semi or auto//but it should act according to the switch position..

all my monkeying around..and Ive just made it worse! LOL..

That means that you need a boolean variable to keep track of whether the switch has ever been read as HIGH. Set it whenever the switch is read as HIGH. Then, when the switch is LOW and the flag is true, do whatever you need (play the sound, etc.).

isnt my boolean autoFire? (or I guess thats just a booloean to say do auto fire or not.. but should be true is the switch is in auto mode (1/HIGH)

 //check the fire mode button state  
  if (digitalRead(modeSelect_btn) && autoFire == false) {
    //mode select audio notification       
    putstring_nl("mode select changed: auto");
    Serial.println(digitalRead(modeSelect_btn));
    playcomplete("amode.WAV"); 
    autoFire = true;
  }
  else if (!digitalRead(modeSelect_btn) && autoFire == true) {
    //mode select audio notification    
    putstring_nl("mode select changed: semi");
    Serial.println(digitalRead(modeSelect_btn));  
    playcomplete("smode.WAV");
    autoFire = false;  
  }

currently,.. if the switch is HIGH when powered on.. it does nothing...(mode select switch doesnt do anything)

it boots....

then without me sliding the switch..

it plays the sound..and shows this in serial mon.

mode select changed: semi
0

and then the switch is 'dead'.. toggling it does nothing in serial mon..no sounds..etc..

if I start with switch in LOW position.. everything works as it should..

toggling switch plays correct sound on each 'position'.... puts code in right 'mode' to play the rapid or single fire shots.. outputs to serial monitor correctly..etc..

I guess Im not sure how to implements this boolean variable you suggest to keep track of HIGH..

if(digitalRead(modeSelect_btn) == HIGH){
     //do something
}

but then how do I handle or account for this var/flag in the 'button state checking code'? (posted in this post above?)

thanks

I want the slide switch to dictate if the it does SEMI fire mode or AUTO fire mode

Then, the switch doesn't have to toggle from LOW to HIGH to LOW to mean anything. You simply read the switch, and LOW means one mode and HIGH means the other. Unless you are failing to explain something properly, this seems dead simple.

The fact that you have enabled the pullup resistor is irrelevant. That simply means that every time you read the switch, you get a known value. No floating pin problems.

Hi PaulS- (everyone)

ok…(plot thickens)…

seems it must be something ‘else’ in my code…affecting this…
trimmed down:

seems to work great/rock solid…

#include "WaveUtil.h"
#include "WaveHC.h"

//project variables
SdReader card;    // This object holds the information for the card
FatVolume vol;    // This holds the information for the partition on the card
FatReader root;   // This holds the information for the filesystem on the card
FatReader params; // This is the file that holds the sketch variables/data
FatReader f;      // This holds the information for the file we're play
WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time


const int modeSelect_btn =  2;
boolean autoFire;

void sdErrorCheck(void){
  if (!card.errorCode())
  {
    return;
  }
  putstring("\n\rSD I/O error: ");
  Serial.print(card.errorCode(), HEX);
  putstring(", ");
  Serial.println(card.errorData(), HEX);
  while(1);
}

void setup() {  
  Serial.begin(9600);
  //pin2 mode select  
  Serial.print("MODE SELECT CHECK: ");
  Serial.println(digitalRead(modeSelect_btn));
  pinMode(modeSelect_btn, INPUT);
  digitalWrite(modeSelect_btn, HIGH); //no float  
  //pinMode(modeSelect_btn, INPUT_PULLUP);
  autoFire = digitalRead(modeSelect_btn);
  Serial.print("MODE SELECT CHECK AFTER (FINAL): ");
  Serial.println(digitalRead(modeSelect_btn));

  //SD card set-up
  //  if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
  if (!card.init()) {         //play with 8 MHz spi (default faster!)  
    putstring_nl("Card init. failed!");  // Something went wrong, lets print out why
    sdErrorCheck();
    while(1);                            // then 'halt' - do nothing!
  }
  // enable optimize read - some cards may timeout. Disable if you're having problems
  card.partialBlockRead(true);
  // Now we will look for a FAT partition!
  uint8_t part;
  for (part = 0; part < 5; part++) {     // we have up to 5 slots to look in
    if (vol.init(card, part)) 
      break;                             // we found one, lets bail
  }
  if (part == 5) {                       // if we ended up not finding one  :(
    putstring_nl("No valid FAT partition!");
    sdErrorCheck();      // Something went wrong, lets print out why
    while(1);                            // then 'halt' - do nothing!
  }
  // Lets tell the user about what we found
  putstring("Using partition ");
  Serial.print(part, DEC);
  putstring(", type is FAT");
  Serial.println(vol.fatType(),DEC);     // FAT16 or FAT32?
  // Try to open the root directory
  if (!root.openRoot(vol)) {
    putstring_nl("Can't open root dir!"); // Something went wrong,
    while(1);                             // then 'halt' - do nothing!
  }
  
  // Whew! We got past the tough parts.
  putstring_nl("Ready!"); 
  //continue on with timer function assignment
  TCCR2A = 0;
  TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20;
  //check it saftey is on for boot up options
  TIMSK2 |= 1<<TOIE2; 
}
//start timer / switch checking code?
SIGNAL(TIMER2_OVF_vect) {
  //check_switches();
}

void loop() {  
  //check the fire mode button state  
  if (digitalRead(modeSelect_btn) && autoFire == false) {
    //mode select audio notification       
    putstring_nl("mode select changed: auto");
    Serial.println(digitalRead(modeSelect_btn));
    playcomplete("amode.WAV"); 
    autoFire = true;
  }
  else if (!digitalRead(modeSelect_btn) && autoFire == true) {
    //mode select audio notification    
    putstring_nl("mode select changed: semi");
    Serial.println(digitalRead(modeSelect_btn));  
    playcomplete("smode.WAV");
    autoFire = false;  
  }
}

// Plays a full file from beginning to end
void playcomplete(char *name) {
  // call our helper to find and play this name  
  playfile(name);    
  while(wave.isplaying){
    //do whatever while playing: *keeps you in loop careful.
  }
  //is done playing
}


void playfile(char *name) {
  // see if the wave object is currently doing something
  if (wave.isplaying) {// already playing something, so stop it!
    //putstring_nl("stopping current audio.........."); 
    wave.stop(); // stop it
  }
  // look in the root directory and open the file
  if (!f.open(root, name)) {
    putstring_nl("Couldn't open file "); 
    Serial.print(name); 
    return;
  }
  // OK read the file and turn it into a wave object
  if (!wave.create(f)) {
    putstring_nl("Not a valid WAV"); 
    return;
  }  
  wave.play();
}

(attached as well… as: modeSelect_baseTest.ino)

however… when I transplant…or have the same stuff in my LARGER sketch… things act CRAZY!..(as outlined above… makes sound on boot if HIGH… DEAD slider switch if booted up in wrong position…etc)

attached is a sketch that I am trying to fit this all into, together…

so in the alone sketch…it seems to work fine… and be solid… when I have the same in the ‘all-in-one’ bigger sketch… it doesnt work…

*PLEASE, outside of all the other coding suggestions, Im just trying to figure out the modeSelect portion…
of why it only works when the switch is in LOW mode when powered on… but in HIGH mode doesnt.

I know I have some optimizing to do… and will, once I get some resemblance of a working sketch. :slight_smile:

(like I know I can remove the commonCathode check when Im done with testing… as i know I’ll be using a commonAnode for the final project…etc… actually I’ll remove that garbage now!)

Im sure there are also much better (more efficient) ways to do what Im trying to… so to answer any 'WHY DID I DO…X, Y, Z?"…

well because either the best/only way “I” knew how… or really just dont know any better yet. :slight_smile:

Im concerned about ‘memory’… (because I have alot more I want to add to the sketch) lol…

when the sketch uploads…Im not even using half:
Binary sketch size: 12820 bytes (of a 32256 byte maximum

but when I run the freeRam() function…
it says this: Free RAM: 220

so I question it?

DC_17_OSv4.ino:
again… this sketch/file attached works how I want and believe it should… ONLY when it powers up with the slider in LOW position. If it powers up with it in HIGH position… (doesnt work).

Serial monitor output when switch in LOW mode: (correct)… all on power-up…no manual touching of switches
Free RAM: 221
3
0
0

MODE SELECT CHECK: 0
Using partition 1, type is FAT16
Ready!

Serial monitor output when switch in HIGH mode: (incorrect)… all on power-up…no manual touching of switches
Free RAM: 221
3
0
0

MODE SELECT CHECK: 1
Using partition 1, type is FAT16
Ready!
mode select changed: automatic

^not sure why that gets triggered?

modeSelect_baseTest.ino
this is a trimmed up version… with ONLY the selectMode (and audio) stuff… and I am in the understanding/belief that these ‘parts’ are the SAME as in the MAIN/bigger sketch… (no changes to them… outside of the extra code for other events/actions)

and it seems to work just fine/rock solid no matter what position the slider switch is in open power-up… seems to work and mirror the values correctly… (plays the sounds…etc)

am I missing something?
or doing something wrong/incorrectly? (with example… obviously something is incorrect) :slight_smile:

its not like Im not trying here… LOL…
I’m posting code (in tags),
Posting trimmed and full code/sketches (that compile) :wink: to appease both type of people…

appreciate the help…
thanks!

modeSelect_baseTest.ino (4.22 KB)

DC_17_OSv4.ino (14.8 KB)

Change this…

  if (digitalRead(modeSelect_btn) && autoFire == false) {

    //mode select audio notification       

    putstring_nl("mode select changed: auto");
    Serial.println(digitalRead(modeSelect_btn));
    playcomplete("amode.WAV"); 
    autoFire = true;
  }
  else if (!digitalRead(modeSelect_btn) && autoFire == true) {
    //mode select audio notification    
    putstring_nl("mode select changed: semi");
    Serial.println(digitalRead(modeSelect_btn));  
    playcomplete("smode.WAV");
    autoFire = false;  
  }

to this…

  if (digitalRead(modeSelect_btn) {
    autoFire = true;
  }
  else {
    autoFire = false;  
  }

Then do whatever you want with autoFire later. Do you really care that it shanced state, or are you just going to use the state?

well 'when' it changes.. I want to play the audio file. (like in the code)

but I cant have the 'mode select sound clip' playing over & over..

only the once.. on change. :slight_smile:

on a side note..

how come in the stripped down baseTest.ino file.. it seems to work 'fine'..
I didnt change anything except to paste it into the other larger sketch.. and it doesnt work?

xl97:
well 'when' it changes.. I want to play the audio file. (like in the code)

Well, then put an if statement into each portion

  if (digitalRead(modeSelect_btn) {
    if ( !autoFire ) {   // must have changed
    // do stuff here that acts when it changes to true
    }
    autoFire = true;
  }
  else {
    if ( autoFire ) {   // must have changed
    // do stuff here that acts when it changes to false
    }
    autoFire = false;  
  }

I went through… cleaned up some things, and it seems to be working… (although Im not exactly sure what I had missed/done wrong/differently from some of the other attempts posted previously?)

here is the latest version…(in case of curiosity) :slight_smile:

DC_17_OSv4.ino (15.4 KB)

OMG!!..

I’m losing my sanity here!.. ]:slight_smile:

My board must be garbage/messed up…
or this is a memory issue of some sorts??

I can NOT for the life of me figure out why this same scenario keeps happening…

ok…so last post… I was at a STABLE state/code…

I am attaching BOTH sketches for someone to take a look at… and SHOW ME where/how Im being such a FOOL…wher one works FINE… and other breaks/only works when the slider switch is on LOW position on power-up???

DC_17_OSv4.ino:
Works FINE! (as I am intending it to… and how I am expecting the code to react)…
I’m just not done with it… and need to add more functionality…etc… :slight_smile:

DC_17_OSv4_grenade.ino

broken?? will only work correctly/properly, when the slider switch is in the LOW position upon power-up. (yes… odd I know).

the ONLY changes I did to the later sketch was the following:

1.) Delcare a new grenadeButton:

const int grenadeButton = 19;

2.) Added that button/var name to the button array that the checkSwitches() function ‘watches/checks’:

//make button array for easy looping/checking
int buttons[] = {mainTrigger, reloadButton, [b]grenadeButton[/b]};

3.) In the MAIN loop, where it checks the stats of the switches (justpressed[0], justpressed[1],…etc.)
I added another section, to have a routine execute whenever the justpressed[2] (grenadeButton) gets pressed…

//grenade button
  else if (justpressed[2]) {
    justpressed[2] = 0;
    putstring_nl("--grenade launched--");
    playfile("gren.WAV");
  }

I saved, uploaded new sketch w/changes…

*‘grenadeButton’ works fine… as how I am expecting it to work… however, when it powers-up/reboots… I get the same broken/odd behavior that started this whole threadQ!!

if I boot-up with slider switch in LOW position… everything works great…
if I boot-up with slider switch in HIGH position… I get the initial SOUND playing…and the slider switch fails to work/respond at all (work properly!)

PaulS?
lar3ry?

anyone? haha… I need a sanity check? and I messing something up? I only did those quite simple additions to the otherwise working sketch?.. HOW did I break it?
I cant find a flaw in my code… (outside of it being not as streamlined & efficient as it could be)… so Im left to think maybe this has been a memory issue the whole time?

I need to walk away for a few minutes… then came back.

maybe this should turn into a, how to optimize the sketch/code thread :slight_smile: 'cause I cant think of anything else that could be causing this behavior…(at least optimize in baby steps… little things first, so I can actually follow)

Thanks!

DC_17_OSv4.ino (15.4 KB)

DC_17_OSv4_grenade.ino (15.6 KB)