Using International Characters On A US MacBook

Sure, you can use the little Special Characters feature of the Edit menu. Or you can launch Google translate and use the pop-up keyboard.

But it’s a lot faster — and I think easier — if you just learn how to access these characters directly from the keyboard. Fortunately, the most commonly used characters — like à, é, ç and ô, etc. — are intuitive and easy to remember.Continue reading

Managing dot-qmail files

I’ve been using qmail as my MTA for as long as I can remember. The feature I like most is being able to have one-off email addresses I can use across the web that can easily be disabled if I start getting spammed.

For folks who aren’t familiar with qmail, that means I can set up a prefix foo with the extension and have email sent to foo-anytext@mydomain.com without having to reconfigure the server every time I want to create a new temporary email address.

At some point, that address will start getting spam. The bonus is that by using an extension that identifies the site where I used it, I immediately know where the leak started. When the spam shows up, I create a dot-qmail file to bounce email to that address. Over the years, I’ve accumulated a lot of dot-qmail files, so I’ve started using soft-links to manage them. On my server, I set up three dot-qmail files for my account:

.qmail-default controls normal delivery:

./Maildir/

.qmail-bounce will bounce an email:

|/var/qmail/bin/bouncesaying 'Mail is no longer accepted at this address.'

.qmail-bounce-and-deliver will bounce an email as far as the sender is concerned, but the email will still be delivered. This gives me time to slowly retire an email address that may still occasionally receive legitimate email:

|/var/qmail/bin/bouncesaying 'Mail is no longer accepted at this address.'

Once these three files are configured, I can immediately toggle delivery for a specific email address with a single command:

ln -s .qmail-bounce .qmail-anytext

Arduino Series: Working With An Optical Encoder

The Goal

I have an old White 1602 knitting machine that uses a light scanner to produce patterns in the knit fabric. The bed of the knitting machine syncs up with the controller via two obsolete rotary encoders and the stitch patterns are produced as a sequence of pulses causes specific needles to be selected.

The first problem is that the light scanner has a lot of mechanical parts that have deteriorated with age. Parts are no longer available.

The second problem is that the width of the pattern is constrained by the width of the mylar that feeds into the light scanner to product the pattern.

The third problem is that while the light scanner does its job well when it’s functioning, all of its capabilities could be performed more efficiently and accurately by a computer.

My goal is to completely replace the light scanner with newer technology. This post illustrates a prototype for how I might use an optical coder to track the position of the knitting carriage as well as when it changes direction.

Equipment

Arduino Mega 2560 R2
US Digital Optical Encoder S1-1250-I
4 male-to-female jumpers
Electrical tape

About The Encoder

While obsolete, the S1-1250-I encoder is a very capable piece of hardware, but much more expensive than what’s available on today’s market. I used it because I already had one, but the information presented in this post should work with any rotary quadrature encoder. I’ll most likely replace the US Digital with a SparkFun’s COM-11102 1024 P/R Quadrature Encoder I have on order.

About The Approach

There are basically two ways to interface with the encoder: polling and interrupts. A little project I’m playing with will require a considerable amount of accuracy, so I chose to use interrupts as polling might result in missed pulses.

 Wiring

The encoder has 3 outputs: channel A, channel B and index. We’re not going to use index, so we need to make 4 connections — one for each of the two channels, one for power and one for ground. The encoder has raw wires so we need to add pins in order to attach it to the Arduino.

  1. Make sure the Arduino is powered off.
  2. Strip 1/4″ – 3/8″ of insulation from the encoder’s leads for power, ground, channel A and channel B.
  3. Insert the end of each wire into the female end of a jumper and secure with electrical tape.
  4. Connect the power lead to the 5V power pin.
  5. Connect the ground lead to one of the Arduino’s ground pins.
  6. Connect the channel A lead to digital pin 20. This pin is one of the 6 Arduino pins that support interrupts. The other pins with interrupts are 2, 3, 18, 19 and 21.
  7. Connect the channel B lead to digital pin 17.

The Code

/****************************************************************************************

Author:    Brenda A Bell
Permalink: https://www.brendaabell.com/2014/02/arduino-series-working-with-an-optical-encoder/

****************************************************************************************/

#define ENCODER0PINA         20      // this pin needs to support interrupts
#define ENCODER0PINB         17      // no interrupt required
#define CPR                  1250    // encoder cycles per revolution
#define CLOCKWISE            1       // direction constant
#define COUNTER_CLOCKWISE    2       // direction constant

// variables modified by interrupt handler must be declared as volatile
volatile long encoder0Position = 0;
volatile long interruptsReceived = 0;

// track direction: 0 = counter-clockwise; 1 = clockwise
short currentDirection = CLOCKWISE;

// track last position so we know whether it's worth printing new output
long previousPosition = 0;

void setup()
{

  // inputs
  pinMode(ENCODER0PINA, INPUT);
  pinMode(ENCODER0PINB, INPUT);

  // interrupts
  attachInterrupt(3, onInterrupt, RISING);

  // enable diagnostic output
  Serial.begin (9600);
  Serial.println("\n\n\n");
  Serial.println("Ready.");
}

void loop()
{
  // only display position info if has changed
  if (encoder0Position != previousPosition )
  {
    Serial.print(encoder0Position, DEC);
    Serial.print("\t");
    Serial.print(currentDirection == CLOCKWISE ? "clockwise" : "counter-clockwise");
    Serial.print("\t");
    Serial.println(interruptsReceived, DEC);
    previousPosition = encoder0Position;
  }
}

// interrupt function needs to do as little as possible
void onInterrupt()
{
  // read both inputs
  int a = digitalRead(ENCODER0PINA);
  int b = digitalRead(ENCODER0PINB);

  if (a == b )
  {
    // b is leading a (counter-clockwise)
    encoder0Position--;
    currentDirection = COUNTER_CLOCKWISE;
  }
  else
  {
    // a is leading b (clockwise)
    encoder0Position++;
    currentDirection = CLOCKWISE;
  }

  // track 0 to 1249
  encoder0Position = encoder0Position % CPR;

  // track the number of interrupts
  interruptsReceived++;
}

How It Works

Lines 8 – 12 define a few useful constants to make the code more readable. What they do should be obvious from the comments.

Lines 15 – 16 define global variables that will be modified by the interrupt handler.

Line 19 & 22 define other global variables we’ll use inside the Arduino loop.

The setup() function on line 24 configures our channel A and channel B pins for input, attaches an interrupt handler to channel A’s pin and configures the serial port so we can see some diagnostic output. Note that we’re going to interrupt on a rising state change so we know that the state of channel A will always be high when our interrupt is triggered. Using a rising or falling interrupt means:

  • We always know the state of A without having to perform a read: A is always high in a rising interrupt and always low in a falling interrupt.
  • Since we always know the starting state of A, we only have to test the state of B to determine direction and track the current position.

The Arduino loop() function on line 40 does nothing more than print some diagnostic information about what we’re reading from the encoder. To avoid chatter, the loop is tracking current values against previous values to we don’t print information we’ve already seen.

The interrupt handler on line 55 does all the heavy lifting:

  • When the encoder is moving in one direction, the pulse from channel A is leading the pulse from channel B. When the encoder is moving in the other direction, the pulses are reversed.
  • When the state of A and B are equal, B must be leading A, so the encoder is turning counter-clockwise. Otherwise, A is leading B, so the encoder is turning clockwise. Remember when we configured our interrupt to fire on rising? The state of channel A will always be high, so we only need to check the state of channel B to determine direction.
  • By comparing A to B instead of hard-coded constants, we can change the interrupt between rising and falling without breaking the interrupt handler.

The code on line 75 keeps the counter within the range 0 to 1249. This would allow us to compute angle or synchronize the position of the encoder to some other device.

The code on line 78 is an extra bit of diagnostic info we can use to track how many times our interrupt has fired.

Further Discussion

It’s much easier to understand how the interrupt handler works if you understand what’s happening when you turn the encoder shaft and reverse direction.

When you turn the encoder’s  shaft clockwise, A is leading B. This results in 4 distinct transitions that are repeated over and over as long as the shaft continues rotating in the same direction.

AB
HIGHLOW
HIGHHIGH
LOWHIGH
LOWLOW

What’s important is this:

  • The inputs are latched, meaning that when we read B’s value from A’s interrupt handler the value we get is B’s state as it existed at the time the interrupt handler was fired. 
  • The handler is fired when A goes high.
  • When the shaft is turning clockwise, the handler is fired between the first two transitions —before B goes high — so we know the shaft is rotating clockwise when A is high and B is low.

If the shaft is turning clockwise and you stop turning, A remains high and B remains low.

If the shaft then starts turning counter-clockwise, B is leading A. This means that B has to go high before A’s interrupt fires again. Therefore, when both A and B are high, the shaft must be turning counter-clockwise.

Some makers may be inclined to use interrupts on both A and B. Unless you have an application where you absolutely must perform some action between A and B going high in both directions, the second interrupt is completely unnecessary. Interrupts are an expensive, limited resource so it’s wise to only use them when you need them.

References

http://playground.arduino.cc/Main/RotaryEncoders#Example1

The New & Improved HTTP 503 Error Page

Ed Henry:

People are still getting the same error messages they got three weeks ago.

Jay Carney:

Not so. I think you’re confusing error messages with the queueing message, which is quite a different thing entirely.

So one is telling you the system is too busy to handle your request and the other one is telling you the system is too busy to handle your request. Got it!

Can’t connect Twitter to Facebook

Scenario: You go to your Twitter profile page and attempt to connect your Facebook account, and no matter what you do all you see is There was a Twitter server error. The error has been reported to our engineering team. Please try again as it might be a temporary problem.

Solution:

  • Log in to Facebook and remove Twitter from your Facebook apps.
  • Log in to Twitter and verify that Facebook is disconnected.
  • Log out of both Facebook and Twitter.
  • Clear all of your Facebook and Twitter cookies.
  • Close your browser.
  • Launch your browser and log in to both Facebook and Twitter.

Now try to connect Facebook to your twitter profile again. It should work this time.

It doesn’t matter whether Android is better than IOS

The problem has never been Android. Android is Android and IOS is IOS. They’re just different.

The problem is the device manufacturers and software publishers. For two years I went through a cycle where my Motorola Droid wouldn’t pair with my Garmin GPS. Every software update on one side or the other broke connectivity. Garmin blamed it on Moto and Moto blamed it on Garmin and it was broken more often than it worked.

My two year old iPhone has never failed to connect — not once.

Moral of the story: When it comes to technology, being better doesn’t matter. If it doesn’t work, it really doesn’t matter whether it’s genius or a piece of crap.

For every market, there’s an equal anti-market.

Apple Is Doomed!

Not. The Motley Fool is living up to its name in the Doug Erhman interview.

It doesn’t take a genius to look at the past successes and failures of Microsoft, Google, HP and others to realize that new and different is not always new and better, and certainly not always a consistent measure of the person at the helm.

Me thinks that maybe Erhman should be ousted for not answering the questions with anything of substance.

Has anyone stopped to think that while the pundits are manufacturing doom and gloom out of the rumors about release delays for an imaginary (unannounced) product (iWatch)? Or a CEO that hasn’t wow’d the tech community in two OMG-that’s-way-too-long years? After all, isn’t it obvious that Steve Jobs invented, developed and released all of his cool gadgets in mere weeks or months?

I’m secretly hoping that Wall Street bets the farm on this bit of news and Apple’s stock takes a nose dive. Because I believe that Steve Jobs was a really smart guy… smart enough that in those ten years he was grooming his successor, he may have actually planned for a few surprises to emerge after his death. And I’m still hoping for a chance to redeem myself for not buying Apple at $90.

Online Clipboard

Ever wanted a quick way to share some text but it’s too big to paste into Skype and email’s too slow for true collaboration?

Check out pastebin.com. Simple with support for syntax highlighting and automatic expiration.

Adding a COM port to a Windows Fusion VM on Mac OS X

This article applies to the following:

  • Mac OS X 10.8.2
  • VMWare Fusion 5.0.2
  • Windows XP SP3
  • RadioShack USB-to-Serial Adapter
  • Macbook Pro Retina

Install the Mac OS X drivers:

  • Download http://www.xbsd.nl/pub/osx-pl2303.kext.tgz and unzip to a temporary directory.
  • Open a terminal window and execute the following commands:

  • cd /path/to/osx-pl2303.kext
    sudo cp -R osx-pl2303.kext /System/Library/Extensions/
    cd /System/Library/Extensions
    sudo chmod -R 755 osx-pl2303.kext
    sudo chown -R root:wheel osx-pl2303.kext
    sudo kextload ./osx-pl2303.kext
    sudo kextcache -system-cache

  • Launch System Preferences and verify the drivers loaded properly. Under Network, you should see a device labeled PL2303.

Since Mac OS X and Windows can’t use the device at the same time, you’ll need to unload the kext. Open a terminal window and execute the following command:

sudo kextunload /System/Library/Extensions/osx-pl2303.kext

Note that you’ll need to repeat this command if you reboot your MacBook.

Install the Windows drivers:

  • Download the 260-0183 RadioShack driver from the RadioShack support site. Extract the files to a temporary directory.
  • Use the VMWare menu to connect the Radio Shack USB Device to the VM. Windows will launch the New Hardware applet. When prompted, instruct Windows to install the driver from the temporary directory containing the extracted driver files.
  • Launch Device Manager and verify the RadioShack device appears under Ports (COM & LPT).