2014-05-31

Bluetooth thermometer

Some time ago I measured the temperature inside my fridge with a Raspberry Pi and a TMP36 sensor. That was cool, but obviously you don't need an entire computer running Linux just to report temperature. So I made a wireless thermometer using Adafruit's Trinket, a DHT22 temperature/humidity sensor and a cheap Bluetooth serial module from dx.com. Here's what it looks like:



And here's a diagram:



The connections are pretty straightforward, I used three AA batteries for power, which was fine for the 3.3V Trinket and the Bluetooth module. I connected the DHT22 sensor to the regulated 3.3V output on the Trinket. I only connected the RX pin on the Bluetooth module, because I was only going to be sending data. The DHT22 sensor also has one data pin and there's a 10K pull up resistor between the data pin and VCC.

As far as software goes, I used this library to talk to the DHT22 sensor, because the one from Adafruit that I used previously with a real Arduino didn't want to work on a Trinket for some reason. I also used this SendOnlySoftwareSerial library because I was only sending data and with the regular SoftwareSerial library the sketch wouldn't fit in Trinket's limited memory. You can the sketch I used here, it's a simple modification of the example sketch that comes with the DHT22 library.

To read the temperature from this thermometer, you need a device (phone, tablet, computer) with Bluetooth and a terminal application. It prints the temperature and humidity every two seconds:

2014-05-30

Bitcoin price ticker

You can get some cool stuff for cheap on dx.com. For example this TM1638 display board costs around $8 and has eight 7-segment digits, eight two-color LEDs and eight buttons. I connected it to a Raspberry Pi and made a Bitcoin price ticker:



Even though I didn't get any documentation with the board, the protocol it uses is well known on the Internet, I found this Arduino library and ported the parts I needed to Python to run on the Pi. You need three GPIO pins on the Pi to connect to DIO, CLK and STB0 pins on the board. You also need to connect the VCC pin on the board to the 5V pin on the Pi and GND to any of the grounds.

Getting a price to display is easy, Bitcoin exchanges usually provide this data via a JSON service. You can see my code here.

Like I mentioned before, the display board also has buttons, so it would be nice to extend this to display prices from multiple exchanges, using the buttons to select which price you want to see.

2013-10-30

Morse code USB keyboard

Further exploring the capabilities of Arduino Micro as an input device, I made a telegraph key that works as a regular USB keyboard. Here's a demonstration (please excuse my lack of Morse code skills):



For the input part I used the CapacitiveSensor library. The way it works is there's a send pin and a receive pin. You put a resistor between the two pins (I used 1 megaohm) and then also connect a piece of metal to the receive pin that will act as the sensor that you touch. I used a copper coin soldered to a piece of wire. (One serious limitation of capacitive sensing done this way is that the Arduino needs to be grounded, so for example it may not work well with battery-powered laptops.)

I also added a buzzer for feedback, the one I used makes a sound when the signal pin is driven low.

Here's the sketch that's running on the Arduino. As you can see the transmission speed is fixed (though it wouldn't be hard to make it adapt to the observed speed).

If you're a Morse code enthusiast, I also recommend my Android application that listens to Morse code using your smartphone's microphone and translates it to text.

2013-10-25

Emergency mute button

Don't you hate it when one of the fifteen tabs you just opened decides to autoplay some video with an obnoxious audio track? Pressing the mute key on my keyboard just doesn't convey the feelings I have at that moment. I want to hit something hard. That's why I made this emergency mute button:



It connects over USB and speaks the regular HID protocol, so it works with any computer with no additional software or drivers. I got the button itself for 7 dollars on eBay. Inside it there are two screw terminals that are normally connected and get disconnected when you press the big red button (to connect them again you have to twist the button). I connected one of the terminals to one of the digital pins on an Arduino Micro and the other terminal to the ground pin.



Then it was a matter of writing the software for the Arduino that would send the right key events over USB to the computer. Arduino Micro is based on the ATmega32u4 chip (like the Leonardo), so it can act as a USB keyboard out of the box. Problem is, by default the library only knows how to send regular key events, not media keys like mute or volume control. So it requires a slight modification, adding the appropriate HID descriptor and key events. Fortunately I didn't have to figure it all out by myself, because Stefan Jones provided a helpful description of the modifications necessary. With that all that was left was writing the simple sketch reproduced below. It reads the pin that the button is connected to and when it detects a change, it sends the mute key event. (You will notice a slight problem with this: it sends the same event to mute and to unmute the audio. So if the state of the button is out of sync with what the computer thinks, it will work the other way round.)

int sw = 2;

void setup() {
  pinMode(sw, INPUT);
  digitalWrite(sw, HIGH); // pull-up
}

int prevstate = 0;

void loop() {
  int state = digitalRead(sw);
  if (prevstate != state) {
    prevstate = state;
    Remote.mute();
    Remote.clear();
    delay(5); // debounce
  }
}

2013-02-12

Google Authenticator watch

TIMESQUARE is an LED matrix watch, sold by Adafruit in kit form. It has an ATmega328 chip inside, which is interesting, because it means it is programmable using the Arduino IDE. That opens up several possibilities. You could design your own watch faces or you could extend lunchtime by an extra 12 minutes every day. I thought it would be cool to turn my watch into a 2-step authentication token for my Google account.

If you enabled 2-step authentication on your Google account (which you should definitely do, BTW), you know the way it works is you have an app on your phone called Google Authenticator that displays six-digit codes that change every 30 seconds. When you log in, you enter the currently displayed code in addition to your password. That way when bad people get a hold of your password, they still cannot use your account, because they don't have the code. (BTW, this isn't specific to Google accounts, the authentication scheme is described in RFC 6238 and is used by other services like Dropbox and LastPass. You can even set it up so that your own servers ask you for a code when you ssh into them.)

Where do the codes come from? When you set up 2-step authentication, the service (for example Google) gives you a secret that is then stored in the app (it's usually done through a QR code so that you don't have to type in long sequences of numbers). The app generates codes by taking the secret together with current time and performing some cryptographic operations on them (mostly the SHA-1 hash function). There's no reason we can't do the same on our TIMESQUARE watch and indeed someone has already implemented the algorithm on Arduino. I took that implementation and put it as another display mode on the watch, showing the six-digit code using the marquee effect normally used to display time.



If you want to try it on your watch, you can download the code here. You will need to install Adafruit's original code for the watch and their GFX library in your Arduino IDE. You're also going to need a way to program the watch from your computer. I used Adafruit's FTDI Friend. They have a tutorial on how to do this.

The authentication secret is currently hardcoded in the TOTP.ino file. I should probably make it so that it's possible to set the secret using the buttons on the watch, but right now you're going to have to set it manually in the hmacKey1 variable. Google gives you the secret in Base32-encoded form, but you can easily convert it to an array of bytes using the following Python code (remove the spaces from the Base32 string Google gives you):
import base64
print ', '.join([hex(ord(i)) for i in base64.b32decode('JBSWY3DPEHPK3PXP')])
Be aware that compiling code using the Arduino IDE can leave some intermediate files in the /tmp directory (or its equivalent on other operating systems). You should clean them up to remove traces of the secret from your computer.

2013-02-11

Laser tripwire

Somebody call Catherine Zeta-Jones, because I have a laser tripwire.



I made it using an Arduino, a laser diode, a photocell (light dependent resistor) and a piezo buzzer. The laser and the detector are in the same place, so it requires a mirror to bounce the laser beam off (this way I only need power in one place). Here's what it looks like on a breadboard:



The laser diode is just connected to 5V and ground, so it's always on. The piezo buzzer is connected to digital pin 3 on the Arduino and ground so that we can sound the alarm when the laser beam is broken. The photocell is connected in a voltage divider configuration. One leg of the photocell is connected to 5V, the other to ground through a resistor and to analog pin 0 on the Arduino. The way a photocell works is that it changes its resistance depending on light intensity. When the laser beam hits it, the resistance will be lower than when it doesn't. With the voltage divider, we can read a value on the Arduino's analog pin that will depend on the photocell's resistance and thus detect if the laser beam was broken.

The output voltage in the voltage divider depends on the values of the resistors in the following manner:

Vout = Rfixed/(Rphotocell+Rfixed)*Vin

Depending on the photocell's resistance range, we choose the value of the fixed resistor so that we can have a reasonable threshold value for the output voltage.

Here's the sketch that's running on the Arduino.
const int PHOTOCELL_PIN = A0;
const int BUZZER_PIN = 3;
// voltage readings are in 0-1023 range
const int THRESHOLD = 500;

void setup() {
  pinMode(PHOTOCELL_PIN, INPUT);
  Serial.begin(9600);
}

long alarmEndTime = 0;

void loop() {
  int level = analogRead(PHOTOCELL_PIN);
  Serial.println(level);
  long time = millis();
  if (time < alarmEndTime) {
    long timeLeft = alarmEndTime - time;
    if (timeLeft % 1000 > 300) {
      tone(BUZZER_PIN, 4000);
    } else {
      noTone(BUZZER_PIN);
    }
  } else {
    noTone(BUZZER_PIN);
    if (level < THRESHOLD) {
      alarmEndTime = time + 3000;
    }
  }
}

Blinkenlights

I think we all agree that every computer is better with blinking lights. In an effort to overcome my fear of electronics, I have recently acquired an Arduino and one of my first projects was a CPU load indicator for my computer:



It was of course inspired by the blinkenlights on BeBoxes and the way it works is very simple. I got a 10 segment LED bar graph and two six-pin 330 ohm resistor networks (they're just five resistors in a single package with one leg of each resistor connected to the sixth common pin). I connected the positive legs of the LEDs to ten digital pins on the Arduino and I connected the negative legs to ground through the resistors. Here's what it looked like during testing:



Then I needed a way to tell the Arduino which LEDs to turn on. An obvious choice was to communicate over USB (which will also provide power). Here's the sketch that's running on the Arduino:
const int FIRST_PIN = 3;

void setup() {
  Serial.begin(115200);
  for (int i=0; i<10; i++) {
    pinMode(FIRST_PIN + i, OUTPUT);
  }
}

void loop() {
  if (!Serial.available()) {
    return;
  }
  int cpu_load = Serial.read();
  int n = (cpu_load+5)/10;
  for (int i=0; i<10; i++) {
    digitalWrite(FIRST_PIN + i, i<n ? HIGH : LOW);
  }
}
And here's the Python program that's running on the computer:
import serial
import psutil

ser = serial.Serial('/dev/ttyACM0')
while True:
    cpu_load = psutil.cpu_percent(interval=0.1)
    ser.write(chr(int(cpu_load)))
As you can see it sends a byte with the CPU load value (0-100) ten times per second. I only tested it under Linux, but the psutil module should also work on Windows and OS X. It can also give you per-CPU core percentages, but that would require more LEDs and some other way to drive them when we run out of I/O pins on the Arduino.