Author Topic: Multiple buttons + pinWake/pinWoke/resetPinWake  (Read 5372 times)

pvogel

  • RFduino Newbie
  • *
  • Posts: 8
  • Karma: +0/-0
    • View Profile
Multiple buttons + pinWake/pinWoke/resetPinWake
« on: January 16, 2014, 07:32:37 PM »
I'm working on a project that will eventually use a parallax 5 state hatswitch button to control stuff on an iPhone/Android device but until my parallax switches arrive I'm using the RGB shield and just trying to get a sense for how things work...

I started with the ledButton sketch and set up pinWake on button1 or button2 to HIGH or LOW state, then go into ULPDelay until a pin wakes me up...

I must be doing something seriously wrong, because with my changes, pressing button 1 wakes the processor up constantly while it's pressed, and button 2 responds once and then neither button 1 or button2 have any effect...

Here's the sketch:

Code: [Select]
/*
Mod of LEDButton example with the intent to allow EITHER button to have the same effect
*/

#include <RFduinoBLE.h>

// pin 3 on the RGB shield is the red led
// (can be turned on/off from the iPhone app)
int led = 3;

// pin 5 on the RGB shield is button 1, pin 6 is button 2
// (button press will be shown on the iPhone app)
int button1 = 5;
int button2 = 6;

// debounce time (in ms)
int debounce_time = 10;

// maximum debounce timeout (in ms)
int debounce_timeout = 100;

void setup() {
  Serial.begin(9600);
  // led turned on/off from the iPhone app
  pinMode(led, OUTPUT);

  // button press will be shown on the iPhone app)
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);

  // this is the data we want to appear in the advertisement
  // (the deviceName length plus the advertisement length must be <= 18 bytes
  RFduinoBLE.advertisementData = "ledbtn";
 
  // start the BLE stack
  RFduinoBLE.begin();
}

int debounce(int state)
{
  int but = button1;
  if (RFduino_pinWoke(button2)) {
    Serial.println("Woke on button2");
    but = button2;
  } else {
    Serial.println("Woke on button1");
  }
  int start = millis();
  int debounce_start = start;
 
  while (millis() - start < debounce_timeout)
    if (digitalRead(but) == state)
    {
      if (millis() - debounce_start >= debounce_time)
        return 1;
    }
    else
      debounce_start = millis();

  return 0;
}

int delay_until_button(int state)
{
  // set button edge to wake up on
  Serial.print("Watching for edge: ");
  Serial.println(state, DEC);
  if (state) {
    RFduino_pinWake(button1, HIGH);
    RFduino_pinWake(button2, HIGH);
  } else {
    RFduino_pinWake(button1, LOW);
    RFduino_pinWake(button2, LOW);
  }
   
  do {
    // switch to lower power mode until a button edge wakes us up
    Serial.println("ULP Sleep");
    RFduino_ULPDelay(INFINITE);
  } while (! debounce(state));
 
  // if multiple buttons were configured, this is how you would determine what woke you up
  if (RFduino_pinWoke(button1))
  {
    // execute code here
    Serial.println("reset button1");
    RFduino_resetPinWake(button1);
  } else {
    Serial.println("reset button2");
    RFduino_resetPinWake(button2);
  }
}

void loop() {
  delay_until_button(HIGH);
  Serial.println("Turn iPhone button on");
  RFduinoBLE.send(1);
 
  delay_until_button(LOW);
  Serial.println("Turn iPhone button off");
  RFduinoBLE.send(0);
}


void RFduinoBLE_onDisconnect()
{
  // don't leave the led on if they disconnect
  digitalWrite(led, LOW);
}

void RFduinoBLE_onReceive(char *data, int len)
{
  // if the first byte is 0x01 / on / true
  if (data[0])
    digitalWrite(led, HIGH);
  else
    digitalWrite(led, LOW);
}

When I run it and watch what's going on in the serial monitor:

Watching for edge: 1
ULP Sleep
Woke on button1
reset button1
Turn iPhone button on
Watching for edge: 0
ULP Sleep
Woke on button1
ULP Sleep
Woke on button1
ULP Sleep
Woke on button1
....
-------- Eventually I RELEASE button1:

reset button1
Turn iPhone button off
Watching for edge: 1
ULP Sleep

If I press button 1 again, the same stuff as above happens.

If I instead press button 2:

Woke on button2
reset button2
Turn iPhone button on
Watching for edge: 0
ULP Sleep

There's no repeating and releasing the button does nothing, the iPhone green button light stays on, neither button1 nor button2 have any effect, though clicking the iPhone app's "button" button does turn the LED on on the shield, so the sketch is still running...

Where am I going wrong?

Thanks,
Peter+

matsk

  • RFduino Jr. Member
  • **
  • Posts: 59
  • Karma: +1/-0
    • View Profile
    • Tinnio IT Konsulting
Re: Multiple buttons + pinWake/pinWoke/resetPinWake
« Reply #1 on: January 16, 2014, 11:37:41 PM »
All code that is within  "void setup()" will happens once when the sketch is started. Ref. http://arduino.cc/en/Reference/Setup

The code that is within "void loop()" will run continuously after the "void setup()" is finished. Ref. http://arduino.cc/en/Reference/Loop

/Mats
« Last Edit: January 16, 2014, 11:39:27 PM by matsk »

pvogel

  • RFduino Newbie
  • *
  • Posts: 8
  • Karma: +0/-0
    • View Profile
Re: Multiple buttons + pinWake/pinWoke/resetPinWake
« Reply #2 on: January 16, 2014, 11:54:33 PM »
All code that is within  "void setup()" will happens once when the sketch is started. Ref. http://arduino.cc/en/Reference/Setup

The code that is within "void loop()" will run continuously after the "void setup()" is finished. Ref. http://arduino.cc/en/Reference/Loop

/Mats

I understand that completely.  But RFduino_ULPDelay(INFINITE) puts things into an ultra-low power state and waits for input from the BLE or an input pin signal edge, (hence the RFduino_PinWake() calls) and, as I said, if I leave things using only one button things work as expected.

Peter+

matsk

  • RFduino Jr. Member
  • **
  • Posts: 59
  • Karma: +1/-0
    • View Profile
    • Tinnio IT Konsulting
Re: Multiple buttons + pinWake/pinWoke/resetPinWake
« Reply #3 on: January 17, 2014, 12:06:08 AM »
Ahh my mistake...

pvogel

  • RFduino Newbie
  • *
  • Posts: 8
  • Karma: +0/-0
    • View Profile
Re: Multiple buttons + pinWake/pinWoke/resetPinWake
« Reply #4 on: January 17, 2014, 12:17:37 PM »
Ahh my mistake...

No problem, thanks Matsk!

Does anyone have an idea on this?  I'm going to need to be able to independently respond to a variety of button inputs soon :-)

Peter+

Dinsen

  • RFduino Newbie
  • *
  • Posts: 2
  • Karma: +0/-0
    • View Profile
Re: Multiple buttons + pinWake/pinWoke/resetPinWake
« Reply #5 on: January 19, 2014, 04:08:50 AM »
I have the same problem when I try to use RGB shield and use both buttons.

pvogel

  • RFduino Newbie
  • *
  • Posts: 8
  • Karma: +0/-0
    • View Profile
Re: Multiple buttons + pinWake/pinWoke/resetPinWake
« Reply #6 on: January 19, 2014, 08:46:40 PM »
I have the same problem when I try to use RGB shield and use both buttons.

I think the problem is with the way the code tries to handle HIGH and LOW transitions.  I now handle a 3 positions of a 5 position switch like this:

Code: [Select]
  RFduino_ULPDelay(INFINITE);
  if (RFduino_pinWoke(button1)) {
    if (debounce(button1, LOW)) {
      RFduinoBLE.send(1);
    }
    RFduino_resetPinWake(button1);
  }
  if (RFduino_pinWoke(button2)) {
    if (debounce(button2, LOW)) {
      RFduinoBLE.send(2);
    }
    RFduino_resetPinWake(button2);
  }
  if (RFduino_pinWoke(button3)) {
    if (debounce(button3, LOW)) {
      RFduinoBLE.send(3);
    }
    RFduino_resetPinWake(button3);
  }

And that works nicely.

Peter+

 

anything