Making Keyboard Accessible Popovers in Bootstrap

In my line of work I must make sure the web interfaces we develop are as accessible as possible for all kinds of users. While trying to figure out why we couldn’t use a focus event as a trigger for the popovers in bootstrap, I came across this issue. Judging by the terse answer from the developers, it doesn’t look like they’re going to bother fixing the problem.

For those of us who are interested in allowing the mouse impaired to take advantage of bootstrap in a cross-browser environment, the following bit of code seems to work nicely:

$('a[rel=popover]').popover()
    .focus(function () { $(this).trigger('mouseover'); })
    .blur(function () { $(this).trigger('mouseout'); });

Seems that Chrome does acknowledge focus events on non-form elements after all. Imagine that.

Decoding a Rotary Encoder

I recently acquired a rotary encoder to use as an input device for my hardware project. Knowing that such encoders make use of Gray code, I cracked open my Digital Design textbook and began coding a sketch for my Arduino. It wasn’t as straightforward as I had hoped.

This isn’t going to be a lesson in Gray code or rotary encoders — you can click the Wikipedia links above for that. This is intended to be a record of the lessons learned while trying to get a reliable, responsive read on the rotary encoder (herein simply “encoder” for brevity) that I have. Google turned up a lot of resources for reading an encoder with an Arduino, but there were a number of problems with them, including:

  • too complicated;
  • too much code (bytes of assembly);
  • too long (cycles); and
  • too unreliable.

Others were just flat out wrong.

From what I read, I decided that an Interrupt Service Routine (ISR) based on the changing levels from the 2 outputs from the encoder was the most reliable way of reading the encoder. Using basic Boolean algebra, I was able to come up with a simple expression to determine if the encoder was rotating clockwise. Where A and B are the previous state bits read from the encoder pins, and C and D are the current bits, the expression representing a clockwise movement can be represented in this truth table:

AB
00 01 10 11
00 0 0 1 0
C 01 1 0 0 0
D 10 0 0 0 1
11 0 1 0 0

The table can be reduced to the following boolean expression:
(A XOR D) AND NOT (B XOR C)

The Arduino code looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
volatile boolean rotating = false; 
static boolean rotating_cw = false; 
 
void rotEncoder() { 
  static byte old = 0; 
  byte in = PIND & B1100; 
  rotating_cw = (!!(old & B0100) ^ !!(in & B1000)) & ~(!!(old & B1000) ^ !!(in & B0100)); 
  rotating = true; 
  old = in; 
} 
 
void setup() { 
  DDRD |= B1100; 
  PORTD |= B1100; 
  attachInterrupt(0, rotEncoder, CHANGE); // ISR for rotary encoder 
  attachInterrupt(1, rotEncoder, CHANGE); // ISR for rotary encoder 
}

By way of a short explanation, the encoder is hooked up to digital pins 2 and 3 on the Arduino, and I’m using direct port manipulation for faster reads than digitalRead(). The bitwise math should be pretty easy to understand if you have done any real programming; the !! expression, however, is a little trick to normalize a truthy expression (non-zero) to 1 with minimal instructions.

Whenever you need to read the encoder, you just check the rotating variable, and, if true, then read the rotating_cw variable to see which direction the encoder is rotating. After reading, set rotating to false to get ready for the next read. It’s small, fast, simple, reliable, and usable in almost any programming application (save for those that require PD2 or PD3; but you can change the code to use any pin that can be used as an interrupt).

Here’s the problem: it’s too fast and too reliable! I was puzzled why my encoder was generating multiple rotations for each detent on the switch, even with fairly long delays between reads. I agonized over the math, the code, and my own sanity. Finally, by sending each read to serial output, I could see that, although the switch had 24 detents per rotation, each detent clocked a full 4 cycles of Gray code! What I really needed was to generate a rotating signal only once per detent.

It turns out the code for doing that is even faster, simpler, and smaller than the above code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
volatile boolean rotating = false; 
static boolean rotating_cw = false; 
 
void rotEncoder() { 
  byte in = PIND & B1100; 
  rotating_cw = in == B1100; 
  rotating = in & B100; 
} 
 
void setup() { 
  DDRD |= B1100; 
  PORTD |= B1100; 
  attachInterrupt(0, rotEncoder, CHANGE); // ISR for rotary encoder 
  rotating = false; // ignore the first reading, which will be false
}

Basically, I need only check for the ending state of the switch after landing on the detent. This requires checking only one of the lines for a signal change and ignoring all others when checking for rotation.

The moral of this story is that, despite using the same basic principles, different rotary encoders work differently, so check your data sheets or conduct signal tests like I ultimately ended up doing. If you’re interested in a function to handle the reading of the encoder without inspecting and manipulating the rotating and rotating_cw variables, here it is:

1
2
3
4
5
int readEncoder() { 
 int dir = rotating ? (rotating_cw ? 1 : -1) : 0; 
 rotating = false; 
 return dir; 
}

This will work with either of the two routines above. A call to readEncoder() will return 0 if the encoder hasn’t rotated, 1 for a clockwise direction, or -1 for a counter clockwise direction. This makes it really handy to keep a running counter based on the rotation of the encoder.

Splitting a Path to a list in Python

At work today I needed to split a file path into it’s various directory and subdirectory components using Python. While the result of os.path.split can be inversed with os.path.join, they don’t do what you might intuitively think they do. A cursory search on Google, while turning up various and sometimes overbuilt solutions, didn’t give me a quick and dirty function to accomplish this task, so I wrote one myself.

In you look up the function definition, os.path.split works like this:

>>> os.path.split(filepath) == (os.path.dirname(filepath), os.path.basename(filepath))
True

The (not really) inverse function, os.path.join, could be more appropriately named os.path.concat, since it actually concatenates its path arguments into a combined path.

A coworker came up with this:

parts = filepath.split(os.path.sep)

However, calling os.path.join using the result will not return the original path if the path is absolute. You can get the original path back using:

 os.path.sep.join(parts)

But generally you want to manipulate the path in some way. A valid path like “/path/to//file” will return [ “”, “path”, “to”, “”, “file” ], which isn’t too helpful when you’re trying to deal with the different parts. Calling os.path.normpath first can help (generally a good idea when dealing with paths of unknown format), but you still end up with “” (an empty string) for the root directory.

Here’s my solution:

1
2
3
4
5
6
7
import os.path
 
def splitpath(path, maxdepth=20):
    ( head, tail ) = os.path.split(path)
    return splitpath(head, maxdepth - 1) + [ tail ] \
           if maxdepth and head and head != path \
           else [ head or tail ]

(code line split for easier reading)

Now “/path/to//file” will return [ “/”, “path”, “to”, “file” ]. You can also get the original path using os.path.join:

>>> os.path.normpath(filepath) == os.path.join(*splitpath(os.path.normpath(filepath)))
True

So there it is, mostly for my reference. Some other pedant might find it useful, too.

AnyPWM Revisited

In my original post, I presented an Arduino sketch that could output PWM on any digital pin. It occurred to me spontaneously that the code was horribly inefficient, both in size and execution. So I’ve refactored the code a bit, and now it appears to work at least as well as the built in PWM functions.

The first thing I realized was that the algorithm I was using to track the signals was horribly inefficient; there was way more code and operations than were necessary, and I was tracking too much information. The other thing I realized was that the pulses were not in sync; that might not be too important for most applications, but there might be an application where timing is more critical.

Here’s the code:

1:   // AnyPWM by Nick Borko  
2: // This work is licensed under a Creative Commons
3: // Attribution-ShareAlike 3.0 Unported License
4:
5: // Manually do PWM using FlexiTimer2
6: // (http://www.arduino.cc/playground/Main/FlexiTimer2)
7: #include
8:
9: // LED to pulse (non-PWM pin)
10: #define LED 13
11:
12: // Period of the PWM wave (and therefore the number of levels)
13: #define PERIOD 256
14:
15: namespace AnyPWM {
16: extern volatile byte pinLevel[12];
17: void pulse();
18: void analogWrite(byte pin, byte level);
19: void init();
20: }
21:
22: // Variables to keep track of the pin states
23: volatile byte AnyPWM::pinLevel[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
24:
25: // Set a digital out pin to a specific level
26: void AnyPWM::analogWrite(byte pin, byte level) {
27: if (pin > 1 && pin < 14 && level >= 0 && level < PERIOD) {
28: pin -= 2;
29: AnyPWM::pinLevel[pin] = level;
30: if (level == 0) {
31: digitalWrite(pin + 2, LOW);
32: }
33: }
34: }
35:
36: // Initialize the timer routine; must be called before calling
37: // AnyPWM::analogWrite!
38: void AnyPWM::init() {
39: // (PERIOD * 64) Hertz seems to be a high enough frequency to produce
40: // a steady PWM signal on all 12 output pins
41: FlexiTimer2::set(1, 1.0/(PERIOD * 64), AnyPWM::pulse);
42: FlexiTimer2::start();
43: }
44:
45: // Routine to emit the PWM on the pins
46: void AnyPWM::pulse() {
47: static int counter = 0;
48: for(int i = 0; i < 12; i += 1) {
49: if (AnyPWM::pinLevel[i]) {
50: digitalWrite(i + 2, AnyPWM::pinLevel[i] > counter);
51: }
52: }
53: counter = ++counter > PERIOD ? 0 : counter;
54: }
55:
56: void setup() {
57: AnyPWM::init(); // initialize the PWM timer
58: pinMode(LED, OUTPUT); // declare LED pin to be an output
59: }
60:
61: byte brightness = 0; // how bright the LED is
62: byte fadeAmount = 5; // how many points to fade the LED by
63:
64: void loop() {
65: // set the brightness of the LED:
66: AnyPWM::analogWrite(LED, brightness);
67:
68: // change the brightness for next time through the loop:
69: brightness = brightness + fadeAmount;
70:
71: // reverse the direction of the fading at the ends of the fade:
72: if (brightness == 0 || brightness == 255) {
73: fadeAmount = -fadeAmount;
74: }
75: // wait for 30 milliseconds to see the dimming effect
76: delay(30);
77: }

Download code

The first thing to notice is that I’ve gotten rid of 2 arrays: state and timer. These are completely unnecessary, and it saves 24 bytes right off the top. Second, I’ve upped my multiplier to calculate the timer frequency to 64, which makes for smoother levels when more pins are being pulsed. Finally, a lot of code in the pulse() function has been replaced with a simple comparison against a single rolling counter, making the CPU time spent in the routine much shorter.

The entire code savings is about 80 bytes from the original, which makes this sketch come in at 2114 bytes, compared to the 1252 bytes of the compiled Fade sketch (862 byte difference). Additionally, the performance is much closer to the built in analogWrite() functionality. I don’t know the exact timing, but the difference is fairly imperceptible to a human, even when pulsing 6 pins (the maximum number of PWM pins on an ATmegaXX8 Arduino).

PWM on Any Digital Pin on Arduino

I recently got an Arduino to play around with. It’s been a few years since I’ve done some electronics hacking, and I wanted to get back into the hobby. There are tons of low cost embedded microcontrollers to play with these days, compared to when I was back in college, so I decided to give the Arduino a try. My first experiment was to emit PWM signals on any of the digital output pins.

My real goal was to learn how to use the hardware interrupt timers in general in the Arduino environment. I knew I would have to do this to implement my impending hardware project to build a 16×8 LED matrix light board. Fortunately doing that is pretty much like any microcontroller, so it’s not too difficult to figure out from the documentation. Even more fortunately, Wim Leers abstracted out all the necessary logic to figure out the current clock speed and timer implementations of various Arduino platforms, making it child’s play to set up an interrupt timer routine. His library co-opts timer 2 and is called FlexiTimer2.

Pulse-Width Modulation is simply manipulating the high and low value durations of a fixed period digital waveform to simulate an analog signal level. Well, maybe it’s not that simple, but you can check out the Wikipedia page to get a more technically correct explanation. In any case, the Arduino bootstrap environment provides PWM output on specific pins through a call to analogWrite. While some ATmega pins support hardware PWM, on others it is done in software using timers. My sketch does this as well:

1:   // AnyPWM by Nick Borko  
2: // This work is licensed under a Creative Commons
3: // Attribution-ShareAlike 3.0 Unported License
4:
5: // Manually do PWM using FlexiTimer2
6: // (http://www.arduino.cc/playground/Main/FlexiTimer2)
7: #include
8:
9: // LED to pulse (non-PWM pin)
10: #define LED 13
11:
12: // Period of the PWM wave (and therefore the number of levels)
13: #define PERIOD 256
14:
15: namespace AnyPWM {
16: extern volatile byte pinLevel[12];
17: extern boolean state[12];
18: extern byte timer[12];
19: void pulse();
20: void analogWrite(byte pin, byte level);
21: void init();
22: }
23:
24: // Variables to keep track of the pin states
25: volatile byte AnyPWM::pinLevel[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
26: boolean AnyPWM::state[12] = { LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW };
27: byte AnyPWM::timer[12] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 };
28:
29: // Set a digital out pin to a specific level
30: void AnyPWM::analogWrite(byte pin, byte level) {
31: if (pin > 1 && pin < 14 && level >= 0 && level < PERIOD) {
32: pin -= 2;
33: AnyPWM::pinLevel[pin] = level;
34: if (level == 0) {
35: // reset the PWM state
36: AnyPWM::state[pin] = LOW;
37: AnyPWM::timer[pin] = 255;
38: digitalWrite(pin + 2, LOW);
39: }
40: }
41: }
42:
43: // Initialize the timer routine; must be called before calling
44: // AnyPWM::analogWrite!
45: void AnyPWM::init() {
46: // (PERIOD * 48) Hertz seems to be a high enough frequency to produce
47: // a steady PWM signal on all 12 output pins
48: FlexiTimer2::set(1, 1.0/(PERIOD * 48), AnyPWM::pulse);
49: FlexiTimer2::start();
50: }
51:
52: // Routine to emit the PWM on the pins
53: void AnyPWM::pulse() {
54: for(int i = 0; i < 12; i += 1) {
55: if (AnyPWM::pinLevel[i]) {
56: if (AnyPWM::timer[i] == 0) {
57: AnyPWM::timer[i] = (AnyPWM::state[i] = !AnyPWM::state[i]) ? AnyPWM::pinLevel[i] : (byte)PERIOD - AnyPWM::pinLevel[i];
58: } else {
59: digitalWrite(i + 2, AnyPWM::state[i]);
60: }
61: AnyPWM::timer[i] -= 1;
62: }
63: }
64: }
65:
66: void setup() {
67: AnyPWM::init(); // initialize the PWM timer
68: pinMode(LED, OUTPUT); // declare LED pin to be an output
69: }
70:
71: byte brightness = 0; // how bright the LED is
72: byte fadeAmount = 5; // how many points to fade the LED by
73:
74: void loop() {
75: // set the brightness of the LED:
76: AnyPWM::analogWrite(LED, brightness);
77:
78: // change the brightness for next time through the loop:
79: brightness = brightness + fadeAmount;
80:
81: // reverse the direction of the fading at the ends of the fade:
82: if (brightness == 0 || brightness == 255) {
83: fadeAmount = -fadeAmount;
84: }
85: // wait for 30 milliseconds to see the dimming effect
86: delay(30);
87: }

Download code

Now, a LED attached to pin 13 (or the surface mounted LED on some Arduino boards), a non-PWM pin, will pulse, just like the Fade sketch in the Examples (you’ll note the loop code is nearly identical).

There are some downsides to this approach. First, the code is 942 bytes longer than using the stock analogWrite call on a PWM pin. Second, since all pins share the same timer, the more pins you write to, the slower the execution. This may be an acceptable trade off, and the timing issue may be mitigated by decreasing the duty cycle (PERIOD) while keeping the timer frequency the same (set in AnyPWM:init via FlexiTimer2::set).

This same approach could be used for other applications than PWM. For example, you could control an RGB LED matrix to provide up to 24-bit color, assuming the processor was fast enough; instead of controlling multiple output pins, you could instead be controlling the individual red, green and blue values for each LED through a serial driver. Or, 16 levels of brightness on a single color LED array (if PERIOD is set to 16), which I am thinking about doing for my LED project.

UPDATE: Don’t use this code! Instead, read my follow-up and download the code!