Monday, December 20, 2010

Facebook Chat Translation

I present to the world my latest invention, FBChatAT. A Facebook Chat Inline Auto Translation tool for Google Chrome. (If you don't use Chrome then click here, install, and be set free.)

Download FBChatAT Here

This extension acts/translates in two ways:

When you receive a message in Facebook Chat, the extension will automatically translate that message into your native language, then insert the translated text underneath the original message. This allows you to review/read the original messages and translation simultaneously while you chat.

Secondly.. To type in your native language and have it automatically translated out: An extra textbox is provided at the bottom left of the screen. Type into this box your text will be translated and shown in the space provided above. If/when you are happy with your outgoing message, press 'enter'. This will push the translated text into the current active chat flyout/window. Press 'enter' a second time to push the message into the chat stream.

The default native and foreign languages are English and Traditional Chinese respectively. You can set your preferred languages in the options page of the extension. (Right click FB button in toolbar and choose options).

You may find the full source for this extension on GitHub.

This extension uses Google Translate for the translation.

Sunday, October 31, 2010

Cat Food Vending Machine

This idea stemmed from something I've wanted to try for quite a while. That is to train a pet to do something, maybe even something convoluted or unnecessary, to get food or a treat.

Well I finally have the opportunity to build such a contraption. We recently adopted an orphan cat, and have also recently acquired a lot of spare time. So here's the goal. A small machine that dispenses treats when the cat pushes a button. Some design goals:

  • Large container for cat pellets that empties FIFO style.
  • Some controlled mechanism of dispensing above-mentioned pellets.
  • Sensor feedback to indicate when pellets had left the machine.
  • UI feedback to indicate state of machine. (Ready, Dispensing, Done)
  • Easy UI for animal to prompt pellet dispensation.

It ended up looking like this..

Front view of the vending machine

The cat is meant to press the paddle and then wait for their surprise to pop out the hole. The machine body is made from a cake box and cardboard. Everything was stuck together with cello-tape. Not the best building materials I know but that's all I had at the time.

I thought it was going to be really easy to teach my cat to interface with the machine... Turns out he got impatient quite quickly, and was probably more fascinated with the sound of the spinning motor, than the treats popping out the front.

A breakdown of the electrical components I used:

  • Arduino Nano
  • ULN2004A Darlington Array
  • Some colored LEDS
  • Resistors. I think anything between 0.5k to 2k should be fine.
  • Photoresistor.
  • Stepper motor of your choice
  • Power source suited to your motor

The following is what I cooked up around the Arduino. A lot of this was trial and error as I am a programmer and not an electrician. Needless to say this was all a large learning curve (which is what I wanted).


  


The final Arduino Sketch ended up looking like the below. It wasn't all that I'd hoped it would be; I had gotten fed up several times with trying to monitor time based operations on the Arduino. My sketch always seemed to end up dying after a few hours?.. After a while of hopeless debugging I resigned to just removing the offending bits of code. Sad I know, but actually not too bothered since this is all for the cat. The initial more-feature-complete-sketch can be found here. That still has the photoresistor feedback and some other time based functions in it.


int motorPin1 = 2;
int motorPin2 = 3;
int motorPin3 = 4;
int motorPin4 = 5;
int spinDelay = 25; // the delay between motor steps
int spinAmount = 220; // how many steps should the motor turn?
int motorState = 0;
boolean motorDirection = true; // used to alternate between motor directions

int redLight = 6;
int greenLight = 8;

int buttonPin = 12; // the pin that the pushbutton is attached to
int buttonState = 0; // current state of the button

void setup() {
pinMode(motorPin1, OUTPUT);
pinMode(motorPin2, OUTPUT);
pinMode(motorPin3, OUTPUT);
pinMode(motorPin4, OUTPUT);

pinMode(redLight, OUTPUT);
pinMode(greenLight, OUTPUT);

pinMode(buttonPin, INPUT);
Serial.begin(9600);
digitalWrite(greenLight, HIGH);
digitalWrite(redLight, LOW);
}

void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
buttonPushed();
}
}

void buttonPushed() {
digitalWrite(greenLight, LOW);
digitalWrite(redLight, HIGH);
for (int i = 0; i < spinAmount; i++) {
spinMotor();
delay(spinDelay);
}
motorDirection = !motorDirection;
// reset state: motor pins low to conserve battery, green light on, red light off
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);

digitalWrite(greenLight, HIGH);
digitalWrite(redLight, LOW);
}

void spinMotor() {
if (motorDirection) {
motorState++;
} else {
motorState--;
}
if (motorState <= 1) {
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
if (!motorDirection) {
motorState = 9;
}
}
if (motorState == 2) {
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
}
if (motorState == 3) {
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
}
if (motorState == 4) {
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, LOW);
}
if (motorState == 5) {
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, LOW);
}
if (motorState == 6) {
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, HIGH);
}
if (motorState == 7) {
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, HIGH);
}
if (motorState >= 8) {
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, HIGH);
if (motorDirection) {
motorState = 0;
}
}
}

What would I change if I were to start again?

Pushing a button or paddle turned out to be way complicated. I thought a nice big paddle was going to be easy for the cat to just stomp on with his feet. I don't think I could have been more wrong. As intuitive as buttons are to humans, they make no sense to animals. Next time I would place the push button in or on the area where the pellets exit the machine. For a -long- time my cat tried to extract pellets out the machine by pushing his paw in the exit hole. This makes a lot of sense now looking back.

I certainly wouldn't use cardboard and cello-tape to build again. The hardest part to manufacture was a device to let pellets out of the store in a controlled fashion. Moreover, a machine like this needs to be built out of something solid and heavy; More than once we came through to the living room to see the machine knocked over with pellets everywhere.

ScannerKeystrokeObserver

A class to automatically detect entries from a hardware device that generates keystrokes (like a barcode scanner).

Demo

This class is designed on the assumption that your barcode scanner hardware will act like a keyboard. As a barcode is scanned a series of keypress events will be generated by the device. If these key events are in fast enough succession (the order of milliseconds), then it can be assumed that a scanner device pushed the series of key events. Otherwise it is just normal human input and will be ignored by the barcode reader class.

How to use

Include the following code in the head of your web page.

 <script src="http://ajax.googleapis.com/ajax/libs/mootools/1.2.4/mootools-yui-compressed.js" language="JavaScript" type="text/javascript" ></script>
<script src="ScannerKeystrokeObserver.js" ></script>
<script>
new ScannerKeystrokeObserver({
onRead: function(v) {
$('txtGlobal').set('value', v).highlight();
}
});
</script>

Get It

Friday, October 29, 2010

ImageCarousel Mootools Plugin

An image carousel thats really easy to implement.

Demo

ImageCarousel was designed for those that might get a little intimidated with the Javascript side of web sites.

How to Use

  1. Copy your carousel images into their own folder inside your project.
  2. Copy ImageCarousel.php into the folder from step one.
  3. Download and unzip the ImageCarousel files into your project folder. They should unzip into a folder called 'ImageCarousel'.
  4. Copy the following code into the head tag of your website.
    <script src="http://ajax.googleapis.com/ajax/libs/mootools/1.2.4/mootools-yui-compressed.js" language="JavaScript" type="text/javascript" ></script>
    <link href="ImageCarousel/ImageCarousel.css" rel="stylesheet" type="text/css">
    <script src="ImageCarousel/ImageCarousel.js" language="JavaScript" type="text/javascript"></script>
  5. Copy the following code into your webpage. This will act as the carousel element.
    <div class="ImageCarousel auto" rel="Images/Carousel/" styles="width: 500px; height: 375px;"></div>
    You need to change/check:
    • The 'rel' attribute should point to the folder where you have stored your images. The url should end with '/'.
    • Your images should all have the same dimensions; Check the Carousel 'width' and 'height' match your image dimensions.

Get It

Monday, February 1, 2010

Information Overload

Information abundant: information pools, information pockets, information streams, information databases; Information sources of so many types delivered in so many formats. I have too much information to manage it properly. Well, when I say 'properly' I mean there's too much to remember all of it, digest all of it, to take full potential of all the data being delivered to me.

I am a child of the information age: When I wake up in the morning the first thing I do is get behind my computer to catch up with the world around me. I've got social networks, business networks, email accounts, and am a programmer so have a multitude of other internet services and jobs running on schedules. I need(read want) to know certain things at certain times. If a client has requested my attention via email I need to know as soon as possible. If it's my mothers birthday I need to know 7am in the morning. If my web server goes down, I need to know five minutes ago.

With so many online services and so many of them offering an RSS/Atom stream about nearly everything; An RSS reader does a good job on keeping me up to date with 66.67% of my knowledge source. But even reading my master RSS feed every morning doesnt provide all the information I need, but more importantly it doesnt invoke some simple actions that I find repetitive when I come across certain data.

  • I have a facebook account; I want to be alerted of birthdays in the early morning.
  • I follow some twitterers'; I only want to view tweets that are re-tweeted.
  • I have family members on Flickr and Picasa; If they post photos then I want to see them, better yet funnel them straight to my wireless photo frame in one merged Media RSS stream.
  • I've got an AreMySitesUp account: I need to urgently know when my servers are unavailable.
  • I've got Gtalk, Skype and AIM acocunts...
  • I have setup FTP locations that clients drop work in...
  • I've got several email accounts...
  • I follow several open source projects on forums, bug trackers, and version releases...
  • I run several projects and each of those have several checks and balances in place to make sure all is in order.

I could go on, but the point is made. I've got so many sources of information of varying types and each hold a certain level of importance or urgency to me. Now I want a central way to organise all of this; A way to manage and schedule my information.

I am a programmer; I'm going to make something. An information engine. This engine will:

  • Store data
  • Consume data stream/trigger inputs
  • Publish stream/alert outputs
  • Provide a management console for all of the above
More on this to come...