Thursday, May 10, 2018

Even Better Living Through Chemistry and (Tiny) Computers

I give you my micro:bit powered don't forget to take your allergy medication solution:

From a software perspective, you're looking at a micro:bit that's coded to act as a countdown timer. As the minutes tick by, each of the 25 LED's are lit up. When all the LEDs are on the countdown has been reached.

From a hardware perspective, you're looking at two wires connected via alligator clip to the micro:bit. Both wires lead to swatches of aluminum foil. One of the swatches is taped to the counter while the other is taped to the bottom of my allergy pill bottle. Resting the pill bottle on the counter causes the circuit to complete and input.pinIsPressed(TouchPin.P0) returns true. Lifting the pill bottle causes the circuit to be broken and input.onPinReleased(TouchPin.P0, ...) is invoked. By using these function calls I can manipulate the micro:bit.

Because I take my allergy medication daily, I have the timer set to 24 hours.

With all of this in place, I need only glance over at the micro:bit to see how many LED's are lit up. When nearly all of them are on, I know that it's been just about a day and I can pop a pill. I'll break the circuit to do so. When I put the pill bottle down again, the count begins a new.

It's software, meets hardware, meets an actual real life problem. Whoo!

I'm impressed that I can connect the micro:bit up to the real world using little more than wires, tape and foil. I've already got plans to enhance my solution by building a Lego platform to hold the pill bottle. It's amazing what you can accomplish with so few components and a bit of code.

Here's the code that powers the micro:bit. Feel free to grab it and re-purpose it.

basic.showIcon(IconNames.Square);

let DURATIONS     = [ 60, 60 * 60, 60 * 60 * 24 ];
let durationIndex = 1;
let timerNow      = 0;
let timerStep     = 0;
let timerRunning  = false;

function eachLed(fn : ( x : number, y : number, i : number) => void) : void {
  for(let i = 0; i < 25; i++) {
    let x = i % 5;
    let y = i / 5;
    fn(x, y, i);
  }
}

function timerReset() {
  timerRunning = true;
  timerNow     = 0;
  timerStep    = DURATIONS[durationIndex] / 25;

  basic.clearScreen();
};

function timerTick() {
  if(!timerRunning) {
    return;
  }

  timerNow++;    
  eachLed((x, y, i) => {
    let special = (x == 2 && y == 2);
    if(!special && (i * timerStep) < timerNow) {
      led.plot(x, y);
    }
  });
  led.toggle(2,2);
}

function timerSelect(offset : number) {
  timerRunning = false;
  durationIndex = (DURATIONS.length + (durationIndex + offset)) % DURATIONS.length;
  basic.clearScreen();
  basic.showNumber(durationIndex);
  basic.pause(1500);
  timerReset();
}

input.onButtonPressed(Button.A, () => { timerSelect(-1); });
input.onButtonPressed(Button.B, () => { timerSelect(1); });


basic.forever(() => {
  if(input.pinIsPressed(TouchPin.P0) && !timerRunning) {
    timerReset();
  }

  timerTick();
  basic.pause(1000);
})


input.onPinReleased(TouchPin.P0, () => {
  timerRunning = false;
  basic.showIcon(IconNames.Target)
}) 

Now, if only I could code a solution to cure my allergies...

No comments:

Post a Comment