Magnethead494
Well-known member
Paul,
as subject states, I made progress. dimming works like it should, the tens bar works as it should.
But small issue- if it's dimmed AND the tens is turned on, then it ignores other commands to the bounce library- IE it will only capture random hit-and-miss movements of the other switches. If I undimm it or turn the tens off, then it works fine.
is it because of the 1.5 second debounce timer of onetwo (line 148)?
Since I have the update run after lowtime has elapsed (line 284) can I simply use a regular debounce period here (which would make onetwo and one duplicate, and I could simply use the latter)
- Steve
On Dec 9, 2012, at 7:36 PM, Paul Stoffregen wrote:
I looked only briefly, but it seems like you're on a good path. Sadly, I simply don't have time to review code much.
If it doesn't work perfectly, the best troubleshooting is to temporarily place Serial.println("message") inside each if / else and watch which ones get printed in the Arduino Serial Monitor while you press and release the switch in different ways. Usually that makes any error in the logic very obvious.
On 12/13/2012 12:04 PM, Steve wrote:
Paul,
I made the changes you described. Haven't tested it yet [Have to run and get parts, do some assembly, and build a computer after waiting for UPS], does the code look right to you, now? I cleaned some other stuff and added more comments to make it easier to understand.
Yes it will trigger the wrong output if the user holds the switch too long, but I am hoping that the instruction "Simply pull down and let go" should not cause a user to hold it down for an extended period of time.
switch position detection occurs at line 216
engaging into ON passes to line 394
disengaging out of ON passes to line 424
the trigger of (ON) passes to line 308
On Dec 9, 2012, at 7:36 PM, Paul Stoffregen wrote:
I'm not sure I completely understand the description below. It sounds like you have a switch that has 3 mechanical positions, but you've connected it to only a single digital input pin.
I believe the simplest solution is probably to use 2 pins, so you can easily determine the actial position.
It sounds like you're attempting to infer the position based on timing? If the input stays low for longer than a certain length of time, then it's in the "ON" position, but if the input goes high before that length of time, then you conclude it was in the "(ON)" position. If a user holds the switch with their finger too long, it'll make the wrong conclusion? When the user puts the switch into the "ON" position, you can't conclude it's in that position until the maximum "momentary press" time as elapsed.
If that's what you're trying to do, I'd use an elapsedMillis type variable. It's also possible to do with reading millis(), as your code does for the 2.5 second timeout, but elapsedMillis does that for you and it's much simpler to use. It appears to be simple an integer that automatically increases every millisecond.
Perhaps something like:
elapsedMillis sw1lowtime = 0;
int sw1waiting = 0;
void loop() {
if (one.fallingEdge()) {
sw1waiting = 1;
sw1lowtime = 0; // begin waiting....
}
if (sw1waiting) {
if (sw1lowtime > 500) {
sw1waiting= 0;
// conclude "ON" position... do whatever happens when "ON"
} else {
if (one.risingEdge()) {
sw1waiting = 0;
// rising edge happened within 0.5 second, conclude "(ON)" just ended... do something....
}
}
}
Ultimately it's not possible to truly detect more than 2 positions with a single digital signal.
Everyone has their own coding style.... but I would try to put all the code that makes these timing decisions in a single place, and I'd use the special elapsedMillis variable type which make the code simpler and lets you focus on the timing relationships you want without needing to clutter your code with a bunch of storing and subtracting millis() values.
On 12/04/2012 07:11 PM, Steve wrote:
Paul,
I've ran into an issue. I have one switch performing two functions, and I use bounce to help tell them apart.
The switch is an ON - OFF - (ON) piece, with both on's tied together [written high] and center grounded. If the switch is up, it turns one output on, if it is in the middle, it turns that output off [like a light switch]. If it is bumped down, it toggles another output- off if it was on, or on if it was off.
I start the process at line 217.
If the switch has changed from OFF to ON or (ON), this would trigger fallingEdge, and sends the thread to updateDisplays(0) [line 292], which then goes to the switch statement's 0 case.
If the switch has changed from (ON) or ON to off, it triggers risingEdge.
If the switch has changed from (ON) to OFF, I want to ignore it. Not sure how to do it?
I connected one oscilloscope probe to pin 40, and another to the physical switch terminal, and started moving the command to turn 40 on/off around in the code.
What I discovered is that somehow, the thread is getting sent to updateDisplays(8) [line 388], even though I have two ways for it NOT to get there. It is completely skipping over fallingEdge, and catching on ridingEdge, but only randomly. Sometimes it works right, sometimes it doesn't.
Is there a "good" way to work around this?
The way I'm doing it now, when the switch state is first changed, it gets to the switch(0) statement, and waits for a bit. If the pin is still low, then it assumes the switch is in the ON position, and performs that action. If the pin is high, it assumes the switch was in the (ON) position, and has been released, and performs the action for (ON). When the switch disengages to trigger risingEdge, I have it double check EEPROM(3) if it's even a legal operation. If it's an illegial operation, I have it assume a false read, and do what it was meant to do. If it is a legal operation, it turns the output for ON low. (The EERPOM(3) is set at line 379 within case(7), which is called at line 268)
It's a complex situation, maybe you can figure it out?
Thanks,
Steve
as subject states, I made progress. dimming works like it should, the tens bar works as it should.
But small issue- if it's dimmed AND the tens is turned on, then it ignores other commands to the bounce library- IE it will only capture random hit-and-miss movements of the other switches. If I undimm it or turn the tens off, then it works fine.
is it because of the 1.5 second debounce timer of onetwo (line 148)?
Since I have the update run after lowtime has elapsed (line 284) can I simply use a regular debounce period here (which would make onetwo and one duplicate, and I could simply use the latter)
- Steve
On Dec 9, 2012, at 7:36 PM, Paul Stoffregen wrote:
I looked only briefly, but it seems like you're on a good path. Sadly, I simply don't have time to review code much.
If it doesn't work perfectly, the best troubleshooting is to temporarily place Serial.println("message") inside each if / else and watch which ones get printed in the Arduino Serial Monitor while you press and release the switch in different ways. Usually that makes any error in the logic very obvious.
On 12/13/2012 12:04 PM, Steve wrote:
Paul,
I made the changes you described. Haven't tested it yet [Have to run and get parts, do some assembly, and build a computer after waiting for UPS], does the code look right to you, now? I cleaned some other stuff and added more comments to make it easier to understand.
Yes it will trigger the wrong output if the user holds the switch too long, but I am hoping that the instruction "Simply pull down and let go" should not cause a user to hold it down for an extended period of time.
switch position detection occurs at line 216
engaging into ON passes to line 394
disengaging out of ON passes to line 424
the trigger of (ON) passes to line 308
On Dec 9, 2012, at 7:36 PM, Paul Stoffregen wrote:
I'm not sure I completely understand the description below. It sounds like you have a switch that has 3 mechanical positions, but you've connected it to only a single digital input pin.
I believe the simplest solution is probably to use 2 pins, so you can easily determine the actial position.
It sounds like you're attempting to infer the position based on timing? If the input stays low for longer than a certain length of time, then it's in the "ON" position, but if the input goes high before that length of time, then you conclude it was in the "(ON)" position. If a user holds the switch with their finger too long, it'll make the wrong conclusion? When the user puts the switch into the "ON" position, you can't conclude it's in that position until the maximum "momentary press" time as elapsed.
If that's what you're trying to do, I'd use an elapsedMillis type variable. It's also possible to do with reading millis(), as your code does for the 2.5 second timeout, but elapsedMillis does that for you and it's much simpler to use. It appears to be simple an integer that automatically increases every millisecond.
Perhaps something like:
elapsedMillis sw1lowtime = 0;
int sw1waiting = 0;
void loop() {
if (one.fallingEdge()) {
sw1waiting = 1;
sw1lowtime = 0; // begin waiting....
}
if (sw1waiting) {
if (sw1lowtime > 500) {
sw1waiting= 0;
// conclude "ON" position... do whatever happens when "ON"
} else {
if (one.risingEdge()) {
sw1waiting = 0;
// rising edge happened within 0.5 second, conclude "(ON)" just ended... do something....
}
}
}
Ultimately it's not possible to truly detect more than 2 positions with a single digital signal.
Everyone has their own coding style.... but I would try to put all the code that makes these timing decisions in a single place, and I'd use the special elapsedMillis variable type which make the code simpler and lets you focus on the timing relationships you want without needing to clutter your code with a bunch of storing and subtracting millis() values.
On 12/04/2012 07:11 PM, Steve wrote:
Paul,
I've ran into an issue. I have one switch performing two functions, and I use bounce to help tell them apart.
The switch is an ON - OFF - (ON) piece, with both on's tied together [written high] and center grounded. If the switch is up, it turns one output on, if it is in the middle, it turns that output off [like a light switch]. If it is bumped down, it toggles another output- off if it was on, or on if it was off.
I start the process at line 217.
If the switch has changed from OFF to ON or (ON), this would trigger fallingEdge, and sends the thread to updateDisplays(0) [line 292], which then goes to the switch statement's 0 case.
If the switch has changed from (ON) or ON to off, it triggers risingEdge.
If the switch has changed from (ON) to OFF, I want to ignore it. Not sure how to do it?
I connected one oscilloscope probe to pin 40, and another to the physical switch terminal, and started moving the command to turn 40 on/off around in the code.
What I discovered is that somehow, the thread is getting sent to updateDisplays(8) [line 388], even though I have two ways for it NOT to get there. It is completely skipping over fallingEdge, and catching on ridingEdge, but only randomly. Sometimes it works right, sometimes it doesn't.
Is there a "good" way to work around this?
The way I'm doing it now, when the switch state is first changed, it gets to the switch(0) statement, and waits for a bit. If the pin is still low, then it assumes the switch is in the ON position, and performs that action. If the pin is high, it assumes the switch was in the (ON) position, and has been released, and performs the action for (ON). When the switch disengages to trigger risingEdge, I have it double check EEPROM(3) if it's even a legal operation. If it's an illegial operation, I have it assume a false read, and do what it was meant to do. If it is a legal operation, it turns the output for ON low. (The EERPOM(3) is set at line 379 within case(7), which is called at line 268)
It's a complex situation, maybe you can figure it out?
Thanks,
Steve
Last edited: