Several things to comment here.
First off, if the joystick puts out 3.3v then it won't damage the BBB. If you can control the wiring of the joysticks (I'm assuming they're just microswitches and you can modify the wiring), then a better plan would be to connect a ground signal to one side of the j/s switch and the BB to the other. Atmel chips have built-in pullups. I can't imagine the BBB has that feature. In which case, connect the signal to Vcc via a 10K or 47K resistor. Add a small capacitor for debounce.
In normal operation, the switch is open. The resistor pulls your signal input to a high state. When you operate the switch, the resistor gets shorted to ground and your input goes low. The capacitor just takes the "edge" off the signal to avoid the rough edges you get with your average switch.
I'd second someone else's comment about using relays. Your bilge pumps operate on +12v with a current of around 2A (give or take). You can use an N-channel MOSFET to drive the pump instead. Connect the + to +12v, and the - to the drain of the MOSFET. Connect the source to ground and the gate to the BBB. Cheaper, smaller and better than a relay. Also put a shunt diode across it.
Make sure to use a MOSFET which has a gate threshold compatible with the BBB output or it won't switch on.
The other advantage of the MOSFET is you can pulse the stepper quite quickly. To avoid the pumps "kicking" when turned on, you would switch them on in software for a millisecond (for example), then leave them off for 9ms. Turn them on for 2 and off for 8, etc, until they're fully on. That way, as you operate the joystick, the motors will rev up, rather than kicking hard over and making small movements difficult if not impossible.
Bouncing, as I am sure you are aware, occurs when the contacts of a switch or button literally bounce off each other when you activate it. This causes, when working digitally, in a rapid succession of on-off-on-off-on signals, ending up finally with the steady state that is intended.
There are two basic methods of debouncing (lit: removing the bounce) - software and hardware. Hardware methods can be broken down into two types - RC filters and flip-flops. The latter requires a two-pole input that is used to toggle the inputs to a bistable flipflop, and the former effectively treats the switch signal as an AC waveform and low-pass filters it (filters out the high frequency switching noise and leaves the basic HIGH/LOW signals intact).
Neither of those are really applicable for writing in Verilog, as you don't have capacitors, and your joystick isn't a two-pole switch, but it's useful to know the hardware options so you can see how they relate to software.
Software debouncing basically involves emulating a low-pass filter in software. The most common way of doing it is to look at the input and say "How long has the input been at this state?", and that of course requires some form of timing.
The simplest method is to do the following:
- Notice when the input has changed state
- Flag that it has changed and clear a counter.
At the same time, driven by the clock, for any inputs with the "changed" flag set:
- Increment the input's counter
- If the counter exceeds a certain limit then clear the "changed" flag and set an output variable to the state of the switch.
That means that every time the switch changes state, which will be multiple times during the pressing of that switch, the counter is cleared, but the changed flag is only set once. Only when the last bounce has happened will the counter be able to count high enough (as it keeps getting reset by the bouncing) to exceed the threshold, and only then will the switches state be passed on to the rest of your code.
The clock wants to be considerably faster than 1Hz. It is generally accepted that any two events that happen faster than 20ms apart appear (to us) to occur at the same time. 50ms starts to become really noticeable, so a debounce period of 10-20ms is usually quite good. So your clock needs to go much faster than that to increment the counter and give good press response resolution. To keep things simple a 1KHz clock is good. That gives a 1ms tick, so when your counter reaches 20 that will be 20ms and a good threshold to have.
Best Answer
For your wide range inputs you could consider a solution that I have used a number of times. Bring your inputs in through a circuit like this:
As shown the input threshold for high/low is set at 2.5V by use of the TLV431. The input signal coming through the 2.2K series resistors are clamped to the 5V supply to keep them in safe input range of the AM26LV32. Outputs swing from rail to rail of 0 to 3.3V for input to the FPGA.