Internet of Thingamajigs

Scrollamajg

Many times, when I’m reading an article on the Internet, I’d really like to kick back, put my feet up, maybe even scoot back from the computer a bit. However, this makes it hard to reach the mouse, putting strain on my arm and wrist.

My first pass at solving the problem was my remote scroller app, which proved extremely useful, and ended up incorporating a whole lot of other stuff, too. However, a touch screen lacks tactile feedback, and hovering my finger or thumb above the screen caused strain in my hand.

My latest (and quite successful ) attempt at this dilemma is my new remote scroller thingamajig:

Remote Scroller Thingamajig

The premise is simple: two buttons; one scrolls up, one scrolls down. It’s built on an esquilo, which connects to my home wifi, and sends the same JSON messages to my computer that my remote scroller android app does. A little bubble wrap covers the sharp edges and makes it easy to hold. USB is only used for power. So with a USB or 2.1mm-plug battery pack, it’s fully wireless!

Download & Code

  • Source Code: Coming Soon… Once I disentangle all of my home specific stuff (i.e., remove hardcoded passwords). Here’s the gist of it:
require("GPIO");
require("HTTPC");

function command(c)
{
  try {
    HTTPC(MY_HOSTNAME, PORT_ITS_RUNNING_ON).post(PATH_AND_SUCH, {command=c}, HTTPC_JSON);
  } catch (e)
  {

  }
}

function scrollup()
{
  command("up")
}

function scrolldown()
{
  command("down")
}

buttons <- {};
buttons[2] <- scrollup;
buttons[11] <- scrolldown;

function runbutton(b)
{
  gpios[b].onfalling(null);
  print(b);
  buttons[b]();
  delay(100);
  gpios[b].onfalling(getcallback(b));
}

function getcallback(b)
{
  return @() runbutton(b);
}

gpios <- {};
foreach (b, f in buttons) {
  local button = GPIO(b);
  button.input();
  button.pullup(true);
  gpios[b] <- button;
}

while (true)
{
  foreach (b, g in gpios)
  {
    if (g.islow())
    {
      buttons[b]();
      delay(100);
    }
  }
}
  • Schematic: Coming maybe… It’s two buttons connected to two GPIOs. Figure it out..

Door cow Bell

The doorbell on my apartment wasn’t working, and I was expecting guests, so I threw together a little push-button / particle.io / webhooks contraption that would play a sound effect on my computer when guests arrived. The design even had the advantage of a mechanical fallback: guests could just shake the thing real hard if the pushbutton wasn’t working.

Door bell

Portable Recording Studio

I got a nifty USB microphone, but it’s a pain in the neck to drag my computer out to the living room where all my instruments are. So, I hooked up the microphone to a nifty beaglebone black. The beaglebone connects to my remote scroller app, so I can conveniently record a song, download it to my phone, and play it back it.

Recording Setup

The wifi dongle can be swapped out for a bluetooth dongle, so that even if I’m top of a mountain, I could still record my banjo playing.

Recording Screenshot

I also taped a webcam to the top of the microphone (because why not), which I can access remotely (again, through the remote scoller app framework).

Temperature Monitor

I like to make coffee Sometimes, though, I forget that I’m making coffee. This could be bad, since that means an oven burner stays on for a while, while all of the water boils out of the kettle.

Luckily, I whipped together a little temperature monitor using a very handy esquilo.

Temperature Monitor

The esquilo reads the temperature from the TMP36 analog sensor every second, converts it to Fahrenheit, and uploads it to my little smart-home web app, where I can view it from anywhere.

Status Page

If I’m traveling during the winter, I can ensure that my heater is working enough to keep the temperature above freezing—and my pipes from bursting. Pretty nifty

Code

  • Temperature.nut:
led <- GPIO(46);

// Configure the GPIO as a digital output
led.output();
led.high();

led.low();

print("Delaying");

if (0) {
    for (local i = 0; i < 7; i++)
    {
        delay(500);
        led.high();
        delay(200);
        led.low();
    }
}

led.high();

print("Starting");

adc <- ADC(0);

function max(a,b)
{
    if (a < b)
        return b
    return a;
}

if (1)
{
    dofile("sd:/temperature_monitor/thermistor.nut")
}

while (true)
{
    local seconds = 10;
    try {
        local http = HTTPC(MY_SERVER);
        local temperature = getTemp();
        local memo = mem();
        http.post(POST_PATH, temperature, HTTPC_JSON);
        http.post(POST_PATH, memo, HTTPC_JSON);

        for (local i = 0; i < seconds; i++)
        {
            delay(i * 1000 / seconds);
            led.high();
            delay(1000 - i * 1000 / seconds);
            led.low();
        }
    }
    catch(err)
    {
        print("HTTPC Err" + err);
        for (local i = 0; i < seconds * 2; i++)
        {
            delay(500);
            led.high();
            delay(500);
            led.low();
        }
    }
}
  • Thermistor.nut:

// Based on https://learn.adafruit.com/tmp36-temperature-sensor?view=all
function v2c(voltage)
{
    return (voltage - 0.5) * 100;
}

function c2f(celsius)
{
    return (celsius * 9.0 / 5.0) + 32.0;
}

function getTemp()
{
    local readings = []
    local num_samples = 11
    for (local i = 0; i < num_samples; i++)
    {
        readings.push(adc.readv(0));
        delay(100);
    }

    readings.sort();

    local voltage = readings[(num_samples - 1) / 2]
    local voltage_spread = readings[num_samples - 1] - readings[0]

    local celsius = v2c(voltage)
    local temperature = c2f(celsius)

    local spread = (c2f(v2c(readings[num_samples - 1])) - c2f(v2c(readings[0])))

    return {temperature = temperature, spread = spread, voltage=voltage, celsius = celsius}
}