Wednesday 30 July 2014

App Update: Bluetooth Macro Input

The Bluetooth Macro Input app has been updated and is now available on Google Play.

New Features

As well as it's existing ability to send text files stored on phone, it is now possible to use voice recognition to transcribe voice to text and send that text via bluetooth in the same way, effectively allowing your phone to act as a dictation machine for your computer, without needing to install additional software on your computer.

Please note the voice recognition uses Google's voice recognition API. As a result, I do not have any control of the quality or accuracy of the voice recognition. It does also mean that Internet access is required to use the voice recognition feature.

Usage guide for the original file-based macro system can be found here.

Requirements Changes

Companion hardware is still required, see the original post for details.

The minimum required version of android is now Honeycomb (Android 3.0)

Sunday 13 July 2014

Dog-controlled treat dispenser part 2

This is the second part of my project to create a dog treat dispenser that my dog, Jack, can operate on his own. For the first part, click here.

Building an enclosure
I thought about 3d-printing an enclosure for the control box, but before I commit the time and effort to designing and printing one, I want to make sure that the project works - and that Jack actually uses it.
So for now, I've managed to fit the electronics into an old business card box, with basic cut outs for the buttons and wiring. It's not pretty, but it works.

The enclosure (the croc clips are for power - final version recycled a charger from a Playstation portable)

The floor switch is connected to the control box by a length of old VGA cable - it's nice and sturdy, and has more than enough wires for this project.

The components for the floor switch

In use
I finally managed to get a short video clip of Jack using it

Future improvements 

The floor switch is too light, as you can see in the video, when Jack uses it, he knocks it across the floor, so I've since mounted it to a bit of wood which helps hold it in place.

The small metal tin that I used to make the contact area larger & easier for Jack to use, ended up making the capacitive switch too sensitive - it basically became like a motion sensor - so I removed that, and used the original metal disc (about 15mm diameter) instead. Although the disc itself is smaller, it still manages to detect capacitance from contact anywhere on the switch, so it works just fine.
The floor switch - unfortunately the hot glue made a bit of a mess, but it's all contained on the underside of the switch, and actually helps diffuse the light a bit.

Source Code (Arduino cores for ATTiny2313
int latchPin = 8;
int clockPin = 12;
int dataPin = 11;
int capBtn = 7;

int plusBtn = 3;
int minBtn = 4;

int enabledLight = 5;

int motorPin = 6;

int treatCount = 0;
int valToDisplay = 0;
int timerBypassPin = 9;
long myTime;
boolean treatEnabled = false;

void setup() {
  //set pins to output so you can control the shift register
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(capBtn, INPUT);
  pinMode(enabledLight, OUTPUT);
  pinMode(motorPin, OUTPUT);
  pinMode(plusBtn, INPUT);
  pinMode(minBtn, INPUT);
  pinMode(timerBypassPin, INPUT);
  digitalWrite(motorPin, LOW);
  digitalWrite(enabledLight, LOW);
  treatCount = 3;

void loop() {
  if (digitalRead(plusBtn) == HIGH) {
    if (treatCount > 8) { treatCount = 8; }
  if (digitalRead(minBtn) == HIGH) {
    if (treatCount < 0) { treatCount = 0; }
  if (digitalRead(timerBypassPin) == HIGH) {
    treatEnabled = true;
  if (
      ((millis() - myTime) < 0) ||
      ((millis()-myTime) >= 3600000)
     ) {
    myTime = millis();
    treatEnabled = true;
  digitalWrite(enabledLight, treatEnabled);

  if (digitalRead(capBtn) == HIGH) {
    if (treatEnabled) {
        digitalWrite(enabledLight, LOW);
        treatEnabled = false;
        digitalWrite(motorPin, HIGH);
        digitalWrite(motorPin, LOW);

  switch (treatCount) {
    case 0: valToDisplay = 0; break;
    case 1: valToDisplay = 1; break;
    case 2: valToDisplay = 3; break;
    case 3: valToDisplay = 7; break;
    case 4: valToDisplay = 15; break;
    case 5: valToDisplay = 31; break;
    case 6: valToDisplay = 63; break;
    case 7: valToDisplay = 127; break;
    case 8: valToDisplay = 255; break;

  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, valToDisplay);
  digitalWrite(latchPin, HIGH);