Why isnt this working? (new to Arduino code)

Sumary:

I have a sensor (switch = nail & spring type) when you flick it…it makes connection.

I tried to use an external interrupt…as I thought that would be the best approach to save other resources for other tasks in my code…

however… I quickly became riddled with BOUNCE issues from that sensor/switch… as the nail & spring made contact more than once every time you ‘flicked it’… wasnt sure how to handle that using an external interrupt… I tried to detach and re-attach the interrupt…but didnt work out so well… I mean I ‘guess’ it worked… but it ‘sometimes’ registered more than one ‘contact’ per hit… even though I believe Im using a timer to ‘delay’ checking for the event for 100ms… which should be enough time to allow for the bounce? (perhaps not?)

and Im not even sure this is a good way to approach this…since the interrupt is really always firing/changing/setting the variable… Im really only delaying checking that var every 100ms

int pin = 13;
int pin2 = 2;
volatile int state = LOW;

long previousMillis = 0;
long interval = 100;
long diff = 0;
boolean disable = false;

void setup(){
  Serial.begin(9600);
  pinMode(pin, OUTPUT);
  pinMode(pin2, INPUT);
  digitalWrite(pin2, HIGH);
  attachInterrupt(0, ISR1, HIGH);
}
void loop(){
  diff = millis() - previousMillis;
  if (diff > interval) {
    //Serial.println("--TIME HAS PASSED--");
    //update timer var 
    previousMillis = millis();
    if(state == HIGH){
      Serial.println("--EVENT TRIGGERED--");
      //tone(8, 350, 50);
      digitalWrite(pin, state);
      delay(50);
      state = LOW;
      digitalWrite(pin, state);
    }
  }
}
void ISR1(){
  state = HIGH;
}

so I posted…and was told not to use interrupts at all…and just use a ‘timer’.

So now Im trying to using this ‘timer’ as my debounce solution… (that is the way to handle it correct?) (no External Interrupt)…

but it seems to ALWAYS be executing the statements for an ‘event’.

even when not flicking the sensor…

int ledPin = 13;
int cPin = 2; 
int cState = LOW;
long cCheck = 0;
long cInterval = 100;
long cDiff = 0;
 
void setup(){
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(cPin, INPUT);
  //digitalWrite(cPin, HIGH);
}
void loop(){
  cDiff = (millis() - cCheck);
  if (cDiff > cInterval) {
    cCheck = millis();
    cState = digitalRead(cPin);
    if(cState == HIGH){
      Serial.println("--EVENT TRIGGERED--");
      //tone(8, 350, 50);
      digitalWrite(ledPin, cState);
      delay(50);
      cState = LOW;
      digitalWrite(ledPin, cState);
    }
  }
}

seems to ALWAYS be reading the cPin as HIGH??

tried to comment out that line so the pin wasnt ‘floating’… but then its always HIGH?

(better with code than I am with hardware)…

this is the demo board I made to test this sensor/switch…

the other two will be checked more or less the same way…except they are ball bearing type sensors/switches…

I basically am looking for a way to ‘track/listen’ to these 3 sensors… at all times. (no bounce…not in my house) =)… and execute a ‘sound’ (or whatever) each time that sensor completes the circuit.

the ballbearing sensors are for X & Y tilt/swing measuring/tracking…

the the nail & spring sensor/switch is to detect a ‘hit’ event…

these are the base, continuous functions I need to do (a few others as well) perform the whole time my project is powered/on

I think maybe my PIN is floating…cant set it HIGH…because that triggers the event…

digitalWrite(cPin, HIGH);

is how you set the internal pull up resistor…yes?

cant set it LOW…cause it dont work that way…

I don't understand why you can't use the internal pull-ups and invert your logic.

sorry.. Im new to hardware and electronics in general..

but are you saying to keep the internal pull resistor 'line'.

digitalWrite(cPin, HIGH);

I have left that on there.. and then checked to see if things were LOW instead of checking for HIGH..

example:

int ledPin = 13;
int cPin = 2; 
int cState = LOW;
long cCheck = 0;
long cInterval = 100;
long cDiff = 0;

void setup(){
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(cPin, INPUT);
  digitalWrite(cPin, HIGH);
}
void loop(){
  cDiff = (millis() - cCheck);
  if (cDiff > cInterval) {
    //Serial.println("--TIME HAS PASSED--");
    cCheck = millis();
    cState = digitalRead(cPin);
    if(cState == LOW){
      Serial.println("--EVENT TRIGGERED--");
      //tone(8, 350, 50);
      digitalWrite(ledPin, cState);
      delay(50);
      cState = HIGH;
      digitalWrite(ledPin, cState);
    }
  }
}

and it doesnt do anything.. never seems to trigger an event.. where as the other way always does..

using external interrupt way 'works'.. but seems to have a bit of bounce still in it.

(although I would need a few more external interrupts besides just 2 if I went that route)..

am I doing somethign else wrong int he code..

this 'sensor/switch' (nail & spring) is hooked up to the digital pin2 and GND on the arduino..

Grumpy Mike told me to do some hardware debounceing I beliebe with resistor/cap I believe (I'll have to re-check)..

but still this code should work even if it was getting BOUNCE..no?

any suggestions?

thanks

I have left that on there.. and then checked to see if things were LOW instead of checking for HIGH..

Yes that is the right thing to do.

this 'sensor/switch' (nail & spring) is hooked up to the digital pin2 and GND on the arduino.

Just do a simple loop and print out the value from pin 2 continuously. Is it changing when you press the button?

Do you get the "Time has Passed" message? I am not sure about your:- if (cDiff > cInterval) { function, if it will do what you think.

int ledPin = 13;
int cPin = 2; 
int cState = LOW;
long cCheck = 0;
long cInterval = 100;
long cDiff = 0;
 
void setup(){
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(cPin, INPUT);
  digitalWrite(cPin, HIGH);
}
void loop(){
  cDiff = (millis() - cCheck);
  if (cDiff > cInterval) {
    Serial.println("--TIME HAS PASSED--");
    cCheck = millis();
    cState = digitalRead(cPin);
    if(cState == LOW){
      Serial.println("--EVENT TRIGGERED--");
      //tone(8, 350, 50);
      digitalWrite(ledPin, cState);
      delay(50);
      cState = HIGH;
      digitalWrite(ledPin, cState);
    }
  }
}

Serial.println("–TIME HAS PASSED–");

‘does’ get printed out the serial monitor when I check (looping over and over of course)…

every time I ‘flick’ the sensor (switch) nothing happens

@Mike-

I tried your simple loop test…seems to work fine:

int ledPin = 13;
int cPin = 2; 
int cState = LOW;
 
void setup(){
  Serial.begin(9600);
  pinMode(cPin, INPUT);
  digitalWrite(cPin, HIGH);
}
void loop(){
  cState = digitalRead(cPin);
   if(cState == LOW){
   Serial.println("--EVENT TRIGGERED--");
   //tone(8, 350, 50);
   digitalWrite(ledPin, cState);
   delay(50);
   cState = HIGH;
   digitalWrite(ledPin, cState);
  }
}

I guess at this point Im un-sure what Im missing…or what part is causing me this problem?

any ideas? or suggestions on where I can/should tart trouble shooting?

also curious as to why you’d think that IF() statement wouldnt work correctly?

Thanks

bump…

did/am I doing something wrong? =)

thanks

Your code is checking to see if the switch is enabled after a period of time has passed. It is not checking to see if there was a connection any time during that period of time.

If you had a switch that could be held in a given state (open or closed), you’d see that the switch was detected, if you held it in that state for the interval you have defined.

I think you need to look at the logic of the program. See if the switch is pressed. If so, do something, then wait for some interval to pass before checking again.

hi, thanks for the reply.. maybe you help me understand then..

void loop(){
  cDiff = (millis() - cCheck);
  if (cDiff > cInterval) {
    Serial.println("--TIME HAS PASSED--");
    cCheck = millis();
    cState = digitalRead(cPin);
    if(cState == LOW){
      Serial.println("--EVENT TRIGGERED--");
      //tone(8, 350, 50);
      digitalWrite(ledPin, cState);
      delay(50);
      cState = HIGH;
      digitalWrite(ledPin, cState);
    }
  }
}

the 'switch' is just a nail & spring type sensor (not an actual button)

I am trying to add in a 'debounce' routine that only checks the state of the sensor every XX ms (or whatever).. some small delay to avoid getting several HIGH/LOW readings on one 'flick/hit' of the sensor..

so I start by checking the 'timer/difference' on each loop interation..

after xx ms seconds.. I update new time var. (cCheck)

and then I read the pin..

check to see if it HIGH or LOW..and do the appropriate actions at that point..

are you saying to try it like this:

void loop(){
  cState = digitalRead(cPin);
  cDiff = (millis() - cCheck);
  if (cDiff > cInterval) {
    Serial.println("--TIME HAS PASSED--");
    cCheck = millis();
    
    if(cState == LOW){
      Serial.println("--EVENT TRIGGERED--");
      //tone(8, 350, 50);
      digitalWrite(ledPin, cState);
      delay(10);
      cState = HIGH;
      digitalWrite(ledPin, cState);
    }
  }
}

check the pin state each loop interation..then only check that value after xx ms??

I guess I dont understand the difference in doing this or that? can you explain?

Also.. doing it the later way..wouldnt I possibly be left with a 'LOW' status if the sensors went on, off, on..off before the 'timer' routine executed?

Thanks..

bump... would still like to understand.

any replies are helpful.

thanks

Have you thought about external hardware de-bouncing?

[edit]Here's an interesting writeup on debouncing - page 2 details methods (hardware and software):

http://www.ganssle.com/debouncing.htm

:) [/edit]