My project, running on a Lilypad Simblee using the SimbleForMobile library, detects a piezo vibration sensor being struck, sending voltage over a threshold of 200 to increase a score (the variable assigned to it is sValue) and then display that score over the BLE connection with the phone it's connected to. I will paste my full relevant code at the bottom of this post, but I will first point out the exact code sections where this issue is happening.
Currently the connection and user interface work correctly, however, because so many vibrations over the threshold are detected in a small period of time, the score increases by around 10 or so every time the sensor is struck. With SimbleeForMobile any blocking code (like delay()) will break the connection and stop the program from running, so I have to work around that.
Currently my score updates like this:
int senseVal = analogRead(sensePin);
if(senseVal > 200){
sValue = (sValue+1);
}
with sValue being the number I want to increase by one each time. Because the sensor vibrates enough to be over the threshold around 10-20 times each time it's struck, sValue ends up increasing by around 10-20 instead of 1. I only want it to increase by 1 each time in the around half second of time that the sensor is actually struck, and I'm having trouble finding a solution to make that happen.
To me, using some sort of debouncing method seems like the best idea, as that is the solution I implemented to decrease how often Simblee sends updates to the phone, with the code section:
if (SimbleeForMobile.updatable){
if ((millis() - lastDebounceTime) >debounceDelay){
SimbleeForMobile.updateValue(scorePlaceholder, sValue);
SimbleeForMobile.updateValue(hScorePlaceholder, hsValue);
lastDebounceTime = millis();
}
}
The above code fixed all of the issues I was having with the Simblee connection getting overloaded with data being sent too fast and causing it to freeze, miss inputs, and crash regularly. Since adding the debounce to my code to limit my update to every second (debounceDelay is set to 1000 ms) the connection has been perfect.
I've tried implementing this same debouncing method into my score increasing code (the first code segment in this post) but it doesn't allow my score to increase beyond its initial value of 0. Does anyone have any suggestions for ways I could limit my sValue variable to only increase by one each time it is struck? For an example of the values I get from sensePin (the sensor itself), it stays at around 30 until it's hit, at which point it goes to around 300 several times (it's different every time but I'd say on average, I get scores over the the 200 threshold around 10 times), then back to the base levels in the 30-35 range.
In case it's unclear exactly what I'm asking, I'm trying to find a way for sValue to increase only by 1 each time my piezo sensor is struck, however each time the piezo sensor is struck, It acts like it's been struck around 10 times because of the extra vibration of the sensor, and so far trying to use a debounce method on it hasn't worked for me, perhaps because I'm already using debounce on the code that updates the variables on the phone's UI (SimbleeForMobile.Updatevalue()). Thank you very much for any advice you can give.
My full code is too long to post here due to the Simblee UI building sections, So I'll post my code up to the loop() section, where all of the relevant code is anyway:
#include <SimbleeForMobile.h>
const int led = 13;
int ledState = LOW;
// Every draw command returns a uint8_t result which is the object id that was
// created. If you wish to change the object later, you'll need this value,
// and if you want to catch an event created by an object, you'll need it
// there, too. Make sure you create these id variables outside of any function,
// as you'll need to refer to them in many other functions.
uint8_t btnID;
uint8_t switchID;
uint8_t titleText;
uint8_t btnText;
uint8_t scoreText;
uint8_t hiText;
uint8_t scorePlaceholder;
uint8_t hScorePlaceholder;
int16_t sValue = 0;
int16_t hsValue = 0;
int sensePin = 5;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 1000;
void setup()
{
pinMode(led, OUTPUT);
pinMode(sensePin, INPUT);
digitalWrite(led, ledState);
// advertisementData shows up in the app as a line under deviceName. Note
// that the length of these two fields combined must be less than 16
// characters!
SimbleeForMobile.advertisementData = "Sidekik";
SimbleeForMobile.deviceName = "Skik_1";
// txPowerLevel can be any multiple of 4 between -20 and +4, inclusive. The
// default value is +4; at -20 range is only a few feet.
SimbleeForMobile.txPowerLevel = -4;
// This must be called *after* you've set up the variables above, as those
// variables are only written during this function and changing them later
// won't actually propagate the settings to the device.
SimbleeForMobile.begin();
}
void loop()
{
int senseVal = analogRead(sensePin);
if(senseVal > 200){
sValue = (sValue+1);
}
if (sValue > hsValue){
hsValue = (sValue);
}
if (SimbleeForMobile.updatable){
if ((millis() - lastDebounceTime) >debounceDelay){
SimbleeForMobile.updateValue(scorePlaceholder, sValue);
SimbleeForMobile.updateValue(hScorePlaceholder, hsValue);
lastDebounceTime = millis();
}
}
// This function must be called regularly to process UI events.
SimbleeForMobile.process();
}