Something obviously wrong with this simple code snippet?

Go To Last Post
21 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi. I don't have permission to post this code so I must keep it to this small snippet.

            uint8_t switch_value = 0xC0 ;      // Both switches off
            if ( ( SWITCH_PIN & TEST_A ) == 0 )
            {
               switch_value &= ~0x80 ;
            }
            if ( ( SWITCH_PIN & TEST_B ) == 0 )
            {
               switch_value &= ~0x40 ;
            }

Is there anything with this code that you can see that may be causing my problem?

problem: TEST_A and TEST_B are physical toggle switches. TEST_B works fine, but some (inconsistent but small) amount of flipping TEST_A causes the code to freeze (reboot required). This is the only place in the code where "switch_value" is ever modified and it is also the only place, beyond initialization, where TEST_A and TEST_B are referenced.

I'm not that versed in bit-wise operands but I think I get the basics and can't see how that could possibly cause an overflow or anything... I'm hoping its plainly obvious to someone with more knowledge.

I'm really sorry, but if "more info required" is your answer then I'll have to try to get permission.

Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The first time TESTA is hit, you remove the corresponding bit in switch_value;
teh 1rst time TESTB is set, the corresponding bit in switch_value is removed, too,

and switch_value will always be zero after TESTA and TESTB have been activated, until Doom's Day (it set to 0x0C only at the init time): the only way to reset it is to reset ...

perhaps you should
explicitly set switch_value after the corresponding actions of TESTA/(resp) TESTB have been done, but as it is programmed, your program behavior is consistent with your description ...

Last Edited: Fri. Sep 7, 2012 - 04:18 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Nothing in the presented code will "freeze". You need a loop that won't exit or similar to achieve that. However could it be that the switch transitions are also generating electrical noise and that's causing EMC issues leading to a CPU lock up or similar?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Good question. If I looped the switch's wires around a ferrite ring a few times, would that eliminate that?

I don't think that's the problem though. I've had the issue independently confirmed on different hardware and its only the TEST_A that causes the problem and never TEST_B and they are both wired exactly the same way.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That did give me something to think about though, so I swapped the wires for A and B and the problem followed the switch, indicating it is a physical issue. And it does seem to be sensitive to the position of the wiring. If you have any tips on how I might address this... my ears are open :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Some more investigation...

I enabled WDT and its still freezing, so I guess its not getting stuck on a bit of code. I'm thoroughly perplexed at this point on what even to try. Are there other tricks other than WDT to automatically reset a frozen AVR?

AVR is Attiny1634

Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, now we're on to something. I took the offending wire and wrapped it through a ferrite ring a few times... voila, it solved the problem. However, that's not a good solution. I'd rather change something on my circuit board rather than relying on people to fix their wiring (I control the board design, but it is retro-fitted into an existing box which has the offending wiring/switch).

This probably now belongs in general electronics though. I'll post there. Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is switch A wired to a pin that supports an external interrupt? And did you enable that external interrupt but don't have an interrupt handler to support it?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are the pull-ups turned on? If not, then the pin has the ability to float.

To me it does not make sense that the problem follows the switch unless the switches are sourced from different supplies.

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks, but I don't think that's the right tree to bark at :)

Switch A is indeed wired to a pin that supports an external interrupt, but Switch B is not. When I swapped the two wires, as I said before, the problem followed the physical switch. That is, after the swap, Switch A was NOT wired to a pin that supports an external interrupt, yet it was still the problem switch.

Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
This probably now belongs in general electronics though
I'll move the thread there so you can continue with the same thread.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

s_mack,

You didn't answer jgmdesign's question about pullups.

Are you using external pullups/pulldowns, or did you enable the internal pullups ?

Also, are you properly debouncing the switches ?

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I didn't see his question until now.

Internal pullups.

Whether "proper" or not, both switches are debounced the same way.

Anyway, I think I have sufficiently demonstrated that clawson's hunch about interference from the switch itself is the culprit. It may be the switch or it could be the wiring... whatever, it went away with a torroid. It is also GREATLY reduced with a larger resistor between the switch and the pin.

I think I'm on the right track now. Thanks guys.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If the design of the board is in Your control... use opto couplers to isolate external circuit ..or less expensively put a low pass filter ( a simple RC affair ) to minimise switch bounce and any EMI.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

s_mack wrote:
Internal pullups.

It is also GREATLY reduced with a larger resistor between the switch and the pin.

You're using both internal pullups AND external (now larger) resistors ?

Sid

Life... is a state of mind

Last Edited: Fri. Sep 7, 2012 - 10:57 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks. I have an RC on each switch, and that's what I was refering to with the need for a larger value.

Basically my circuit hijacks the two switches. I used the same RC values as the original circuit... well, just because :) Increasing the R value has helped. I continue to fine tune.

Originally I thought it must be software. It wasn't.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are the switches driven from the same source? THat was another of my questions? do you have a schematic? It just seems odd you have to go through all the fuss.

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Jim,

Yes, same source. It think the issue here is one of magnetic field as clawson eluded to earlier. I think the problem is simply that the switch wires were unravelled from their respective cable sets (of 6 and 12 wires) thereby enlarging the potential loop. I seriously didn't think it could cause more than a 1 in a million kind of anomaly... let alone a relatively easy-to-reproduce phenomenon! I was sure at first that it must be software related, but I've since gathered enough evidence that it is hardware related that I can't really see any reason to believe contrary.

When I started this thread, I could not get the problem to happen with the B switch, but it would happen within 10 flips of the A switch. Adding a ferrite ring to A's wire virtually eliminated the problem.

I raised A's resistor from R200 to R2K2 and that *seemed* to fix the problem as well, but I think that was just a fluke with how the wiring fell, because after I replaced B's resistor too and put everything back and secured the case... it froze with the very first flip of A!

I then twisted the wires as best I could for A (left B alone) and I was back to a pretty good situation where I could only freeze it with a combination of rapid A and B together. I went back to the ferrite core around both wires and I haven't been able to reproduce the phenomenon since, even after hundreds of rapid flips on both switches.

My problem going forward... how do I know this won't be a problem? I *think* it will be fine because this is a prototype and the wiring for A and B was pulled out of its twisted set. In production runs, we'll have proper connectors so the cable-sets will remain twisted. Still, it scares me that its that sensitive. I'll continue to investigate what I can do to eliminate on board.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here's the vibe I'm getting: You are using Big Honkin Toggle switches with giant springs in them and when the contacts go CLACK they bounce 3 or 4 times about 2ms apart. You have an RC filter across the switch, but the time constant on the filter needs to be selected so that 5 RCs is longer than the bounce time of about 8ms. My crystal ball tells me the RC is Too Short and the program is looping faster than 8ms per loop. The fix is make RC longer and/or add a delay in the loop to only read the switches every 20ms. Then the bounces are Dont Cares.
The next few messages will tell you to rig up a timer interrupt and interrupt handler and run a debouncing algorithm that keeps track of the number of times the switch is closed to decide if the bouncing is stopped. This technique works, but its just Too Complicated for an old country boy like me.

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bobgardner wrote:
bounce time of about 8ms.

add a delay in the loop to only read the switches every 20ms. Then the bounces are Dont Cares.


Assuming you're right about the 8 ms bounce time, you still suffer from bounces in 40% (8/20) of the cases.

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

the switches are actually already read every 20ms.

You're right about them being Big Honkin Toggles :) They're ugly and cheap too.