Announcements

November 24, 2007
Reading for November 27th, are now posted. Enjoy!

October 2, 2007
To upload your thoughtless acts, create a new assignment page like any other lab. You'll see "Thoughtless Acts" listed as one of the assignment options.

May 24, 2008
This site has been archived and is no longer editable. Stay tuned for the next version, coming in the fall!


Introducing the BLouse (Blinking Light-up Mouse)

Project Members: 
Andrew McDiarmid

Description

To create a device that is both input and output, I modified a mouse so that it would beep when moved and light up when buttons were pressed. Vertical speed controls the pitch of the beeping, while horizontal speed controls the volume. Each of the three buttons maps to its own LED. The code for Arduino to interact with a mouse was found on the Arduino discussion boards.

Components Used

Arduino Diecimila

PS/2 mouse

Telephone wire

2 Telephone jacks (modified to fit breadboard)

3 LEDs

3 20-ohm resistors

Piezo electric buzzer

Solderless breadboard

Code

/* BLouse (Beeping Light-up Mouse)
* Andrew McDiarmid
*
* The mouse beeps as it moves, with Y speed controlling pitch,
* and X speed controlling volume. LEDs blink when mouse buttons
* are pressed.
* The program also uses serial protocol to talk
* back to the host and report what it finds.
*/

//Pin 3 is the mouse data pin, pin 2 is the clock pin

#define MDATA 3
#define MCLK 2

//LED pins for lighting up
int redLedPin = 11;
int greenLedPin = 9;
int blueLedPin = 10;

//Piezo speaker pin and variable for its value
int speakerPin = 13;
int val;

/* All code for arduino to talk to PS/2 taken
* from Arduino discussion board
*/

/* Methods for host taking and releasing control
* of clock and data pins for mouse communication
*/
void gohi(int pin)
{
pinMode(pin, INPUT);
digitalWrite(pin, HIGH);
}

void golo(int pin)
{
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
}

// Code for timing host signals to mouse
void mouse_write(char data)
{
char i;
char parity = 1;

// Serial.print("Sending ");
// Serial.print(data, HEX);
// Serial.print(" to mouse\n");
// Serial.print("RTS");
/* put pins in output mode */
gohi(MDATA);
gohi(MCLK);
delayMicroseconds(300);
golo(MCLK);
delayMicroseconds(300);
golo(MDATA);
delayMicroseconds(10);
/* start bit */
gohi(MCLK);
/* wait for mouse to take control of clock); */
while (digitalRead(MCLK) == HIGH)
;
/* clock is low, and we are clear to send data */
for (i=0; i < 8; i++) {
if (data & 0x01) {
gohi(MDATA);
}
else {
golo(MDATA);
}
/* wait for clock cycle */
while (digitalRead(MCLK) == LOW)
;
while (digitalRead(MCLK) == HIGH)
;
parity = parity ^ (data & 0x01);
data = data >> 1;
}
/* parity */
if (parity) {
gohi(MDATA);
}
else {
golo(MDATA);
}
while (digitalRead(MCLK) == LOW)
;
while (digitalRead(MCLK) == HIGH)
;
/* stop bit */
gohi(MDATA);
delayMicroseconds(50);
while (digitalRead(MCLK) == HIGH)
;
/* wait for mouse to switch modes */
while ((digitalRead(MCLK) == LOW) || (digitalRead(MDATA) == LOW))
;
/* put a hold on the incoming data. */
golo(MCLK);
// Serial.print("done.\n");
}

/*
* Get a byte of data from the mouse
*/
char mouse_read(void)
{
char data = 0x00;
int i;
char bit = 0x01;

// Serial.print("reading byte from mouse\n");
/* start the clock */
gohi(MCLK);
gohi(MDATA);
delayMicroseconds(50);
while (digitalRead(MCLK) == HIGH)
;
delayMicroseconds(5); /* not sure why */
while (digitalRead(MCLK) == LOW) /* eat start bit */
;
for (i=0; i < 8; i++) {
while (digitalRead(MCLK) == HIGH)
;
if (digitalRead(MDATA) == HIGH) {
data = data | bit;
}
while (digitalRead(MCLK) == LOW)
;
bit = bit << 1;
}
/* eat parity bit, which we ignore */
while (digitalRead(MCLK) == HIGH)
;
while (digitalRead(MCLK) == LOW)
;
/* eat stop bit */
while (digitalRead(MCLK) == HIGH)
;
while (digitalRead(MCLK) == LOW)
;

/* put a hold on the incoming data. */
golo(MCLK);
//Serial.print("Recvd data ");
//Serial.print(data, DEC);
//Serial.print(" from mouse\n");
return data;
}

void mouse_init()
{
gohi(MCLK);
gohi(MDATA);
// Serial.print("Sending reset to mouse\n");
mouse_write(0xff);
mouse_read(); /* ack byte */
// Serial.print("Read ack byte1\n");
mouse_read(); /* blank */
mouse_read(); /* blank */
// Serial.print("Sending remote mode code\n");
mouse_write(0xf0); /* remote mode */
mouse_read(); /* ack */
// Serial.print("Read ack byte2\n");
delayMicroseconds(100);
}

void setup()
{
Serial.begin(9600);
mouse_init();
}

/*
* get a reading from the mouse and report it back to the
* host via the serial line.
*/
void loop()
{
char mstat;
char mx;
char my;

/* get a reading from the mouse */
mouse_write(0xeb); /* give me data! */
mouse_read(); /* ignore ack */
mstat = mouse_read();
mx = mouse_read();
my = mouse_read();

/* send the data back up */
Serial.print(mstat, BIN);
Serial.print("\tX=");
Serial.print(mx, DEC);
Serial.print("\tY=");
Serial.print(my, DEC);
Serial.println();

/* END OF FOUND CODE-- The rest is my own.
* Read appropriate bits from mstat byte
* and activate LEDs accordingly
*/
if (mstat % 2 > 0){
digitalWrite(redLedPin, HIGH);
}
if (mstat % 4 > 1){
digitalWrite(blueLedPin, HIGH);
}
if (mstat % 8 > 3){
digitalWrite(greenLedPin, HIGH);
}

/* Activate piezo speaker according to
* X and Y speed vectors
*/

val = abs(mx) + abs(my);
if (val == 0){
digitalWrite(speakerPin, LOW);
delay(70); //Just enough time to light the LEDs!
} else {
for( int i=0; i < 100; i++ ) { //Plays note 100 times.
digitalWrite(speakerPin, HIGH);

/* By minimzing the delay between HIGH and LOW
* the square wave is cut off before it reaches full
* amplitude. Increasing the delay increases the amplitude
* up to the maximum amplitude of the square wave.
* Volume is maximized at around 40 microseconds,
* but I chose not to limit the delay.
*/
delayMicroseconds(1 + (abs(mx)));
digitalWrite(speakerPin, LOW);

/* abs(x) is removed so that increasing volume
* does not incidentally lower pitch by increasing
* the overall delay.
*/
delayMicroseconds(1000 - (4 * abs(my)) - abs(mx));
}
}

digitalWrite(redLedPin, LOW);
digitalWrite(greenLedPin, LOW);
digitalWrite(blueLedPin, LOW);

}

Photo

Mouse -- Note blue light

Mouse -- Note blue light

 Board

Board


Comments

definitely looking forward

definitely looking forward to seeing this!!


Powered by Drupal - Design by Artinet