Welcome, Guest. Please Login or Register
YaBB - Yet another Bulletin Board
09.02.2010 at 19:40:15
News: Server upgrade went fine, you are now at the new system


Pages: 1 2 
Touchpad Midi (Read 27254 times)
ludo
YaBB Newbies
*
Offline

Arduino rocks

Posts: 22

Touchpad Midi
09.12.2007 at 22:19:51
 
I've built a MIDI controller around the Arduino.

Started from a scavenged Cirque Glidepoint resistive touchpad (PS/2 compatible), 2x8 LCD (in 4 bit mode), two buttons and a serial Arduino board.



All that take place into a simple enclosure.



The buttons when pressed allow to set the Continuous Controller number by gliding the finger on the touchpad. Left for CC# linked to X and right for Y.




The LCD displays the value sent in MIDI. Some custom characters where coded into the CGRAM in order to have a sort of bar graph. The first line is for X and the second for Y.




I'will post the code after some clean up and referencing all the source. I will also code a MIDI Channel setting and maybe a Note On message.
Back to top
 
 
View Profile   IP Logged
bds
YaBB Newbies
*
Offline



Posts: 12
Australia
Re: Touchpad Midi
Reply #1 - 10.12.2007 at 07:43:11
 
Beautiful work!! I look forward to more details..
Back to top
 
 
View Profile   IP Logged
ludo
YaBB Newbies
*
Offline

Arduino rocks

Posts: 22

Re: Touchpad Midi
Reply #2 - 10.12.2007 at 19:48:45
 
Here is the complete code (first part) . It will be enhanced soon. I've tried to credit all sources. Thanks for usefull code and inspiration. Shall I write this in the playground ?

Code:
#define LCD_RS	8	// Register select
#define LCD_EN	9	// Enable
#define LCD_D4 10	// Data bits
#define LCD_D5 11	// Data bits
#define LCD_D6 12	// Data bits
#define LCD_D7 13	// Data bits

#define MDATA 2	   // Mouse Data
#define MCLK 3	    // Mouse Clock

int midivalueX;
int midivalueY;

int XCC = 19;	    // Midi Continous Controler assigned by default to X
int YCC = 21;	    // Midi Continous Controler assigned by default to Y

/**********************************************************************
 *
 * Mouse
 * Source : Arduino Playground
 * URL : http://www.arduino.cc/playground/ComponentLib/Ps2mouse
 * Author : Unknown
 **********************************************************************/


void gohi(int pin)
{
  pinMode(pin, INPUT);
  digitalWrite(pin, HIGH);
}

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

void mouse_write(char data)
{
  char i;
  char parity = 1;

  /* 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, HEX);
  //  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);
}

/**********************************************************************
 *
 * MIDI
 *
 **********************************************************************/

// Send a MIDI note-on message.  Like pressing a piano key
void noteOn(byte channel, byte note, byte velocity) {
  midiMsg( (0x80 | (channel<<4)), note, velocity);
}

// Send a MIDI note-off message.  Like releasing a piano key
void noteOff(byte channel, byte note, byte velocity) {
  midiMsg( (0x80 | (channel<<4)), note, velocity);
}

// Send a general MIDI message
void midiMsg(byte cmd, byte data1, byte data2) {
  //digitalWrite(ledPin,HIGH);  // indicate we're sending MIDI data
  Serial.print(cmd, BYTE);
  Serial.print(data1, BYTE);
  Serial.print(data2, BYTE);
 // digitalWrite(ledPin,LOW);
}
 


Back to top
 
 
View Profile   IP Logged
ludo
YaBB Newbies
*
Offline

Arduino rocks

Posts: 22

Re: Touchpad Midi
Reply #3 - 10.12.2007 at 19:49:25
 
Second and last part :
Code:
/**********************************************************************
 *
 * LCD
 * Based on 4bit interface example
 * 2006 Massimo Banzi
 * Based on code written by Craig Lee 1998
 * 2007 Ludovic Drochon : LCDbar127
 *
 **********************************************************************/

void lcd_strobe()
{
	digitalWrite(LCD_EN,HIGH);
	digitalWrite(LCD_EN,LOW);
}

/* write a byte to the LCD in 4 bit mode */

void lcd_write(byte c)
{
	if(c & 0x80) digitalWrite(LCD_D7,HIGH); else  digitalWrite(LCD_D7,LOW);
	if(c & 0x40) digitalWrite(LCD_D6,HIGH); else  digitalWrite(LCD_D6,LOW);
	if(c & 0x20) digitalWrite(LCD_D5,HIGH); else  digitalWrite(LCD_D5,LOW);
	if(c & 0x10) digitalWrite(LCD_D4,HIGH); else  digitalWrite(LCD_D4,LOW);
	lcd_strobe();
	if(c & 0x08) digitalWrite(LCD_D7,HIGH); else  digitalWrite(LCD_D7,LOW);
	if(c & 0x04) digitalWrite(LCD_D6,HIGH); else  digitalWrite(LCD_D6,LOW);
	if(c & 0x02) digitalWrite(LCD_D5,HIGH); else  digitalWrite(LCD_D5,LOW);
	if(c & 0x01) digitalWrite(LCD_D4,HIGH); else  digitalWrite(LCD_D4,LOW);
	lcd_strobe();
	delayMicroseconds(40);
}

/*
 * 	Clear and home the LCD
 */

void lcd_clear(void)
{
	digitalWrite(LCD_RS,LOW);

	lcd_write(0x1);
	delay(2);
}

/* write a string of chars to the LCD */

void lcd_puts(const char * s)
{
    digitalWrite(LCD_RS,HIGH);	// write characters

	while(*s) lcd_write(*s++);
}

/* write one character to the LCD */

void lcd_putch(byte c)
{
    digitalWrite(LCD_RS,HIGH); // write characters

	lcd_write(c);
}


/*
 * Go to the specified position
 */

void
lcd_goto(byte pos)
{
    digitalWrite(LCD_RS,0);

	lcd_write(0x80 + pos);
}

/* initialise the LCD - put into 4 bit mode */

void
lcd_init(void)
{


  pinMode(LCD_D7,OUTPUT);
	pinMode(LCD_D6,OUTPUT);
	pinMode(LCD_D5,OUTPUT);
	pinMode(LCD_D4,OUTPUT);
	pinMode(LCD_EN,OUTPUT);
	pinMode(LCD_RS,OUTPUT);

	digitalWrite(LCD_RS, LOW);	// write control bytes

	delay(15);// power on delay

	digitalWrite(LCD_D4, HIGH);	// init!
	digitalWrite(LCD_D5, HIGH); //
	lcd_strobe();
	delay(5);

	lcd_strobe();// init!
	delayMicroseconds(100);

	lcd_strobe();// init!
	delay(5);

	digitalWrite(LCD_D4, LOW);	// set 4 bit mode
	lcd_strobe();
	delayMicroseconds(40);

	lcd_write(0x28);// 4 bit mode, 1/16 duty, 5x8 font, 2lines
	lcd_write(0x0C);// display on
	lcd_write(0x06);// entry mode advance cursor
	lcd_write(0x01);// clear display and reset cursor
}

void downloadcustomcharacter(int CGRAMaddress, byte character[])
{
  for (int i = 0; i<8; i++) //load character bytes in to CGRAM
  {
    lcd_putch(character[i]);
  }
  delay(20);
}

void LCDbar127(int midiValue, short charBlock, short line)
{
  char  SmidiValue[3];
  lcd_goto(0x40*line);

  midiValue = constrain (midiValue, 0, 127); // limit input into 0 and 127
  int pixelPos = (midiValue  * charBlock * 5) / 127;
  int blockPos = (midiValue  * charBlock) / 127;

  for (short idx = 1; idx <= blockPos; idx++)
  {
    lcd_putch(5);
  }

  if (pixelPos % 5) lcd_putch(pixelPos % 5);  // display the not entire block
  blockPos++;

  for (short idx = blockPos ; idx < charBlock; idx++)
  {
    lcd_putch(0);
  }

  lcd_goto(0x40*line + charBlock);
  itoa(midiValue, SmidiValue, 10);
  if (midiValue<10) lcd_puts(" ");
  if (midiValue<100) lcd_puts(" ");

  lcd_puts(SmidiValue);
}

/**********************************************************************
 *
 * Main
 *
 **********************************************************************/

void setup() {
  delay (20);
  lcd_init();
  delay (200);
  lcd_write(0x40);
  //delay(40);
  byte barre1[] = {0x00,0x1F,0x00,0x00,0x00,0x00,0x1F,0x00}; //progress bar characters
  byte barre2[] = {0x00,0x1F,0x10,0x10,0x10,0x10,0x1F,0x00};
  byte barre3[] = {0x00,0x1F,0x18,0x18,0x18,0x18,0x1F,0x00};
  byte barre4[] = {0x00,0x1F,0x1C,0x1C,0x1C,0x1C,0x1F,0x00};
  byte barre5[] = {0x00,0x1F,0x1E,0x1E,0x1E,0x1E,0x1F,0x00};
  byte barre6[] = {0x00,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x00};

  downloadcustomcharacter (0 , barre1);
  downloadcustomcharacter (1 , barre2);
  downloadcustomcharacter (2 , barre3);
  downloadcustomcharacter (3 , barre4);
  downloadcustomcharacter (4 , barre5);
  downloadcustomcharacter (5 , barre6);

  Serial.begin(31250);// midi
  //Serial.begin(9600); //debug
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, INPUT);
  pinMode(5, INPUT);
  pinMode(6, OUTPUT);

  mouse_init();

  lcd_clear();
  lcd_goto(0);
  lcd_puts("TouchPad");
  lcd_goto(0x40);
  lcd_puts("  MIDI");
}

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();

  if (digitalRead(4)==HIGH)
    {
	XCC += mx;
	XCC = constrain (XCC, 0 , 127);
	lcd_goto(0);
	lcd_puts("CC# on X");
	LCDbar127(XCC, 5, 1);
    }
    else if (digitalRead(5)==HIGH)
    {
	YCC += mx;
	YCC = constrain (YCC, 0 , 127);
	lcd_goto(0);
	lcd_puts("CC# on Y");
	LCDbar127(YCC, 5, 1);
    }
  else if (mx!=0 || my!=0 )
  {

	midivalueX += mx;
	midivalueY += my;

	midivalueX = constrain (midivalueX, 0 , 127);
	midivalueY = constrain (midivalueY, 0 , 127);

	midiMsg(0xb0, XCC, midivalueX);
	midiMsg(0xb0, YCC, midivalueY);

	LCDbar127(midivalueX, 5, 0);
	LCDbar127(midivalueY, 5, 1);
    }


}
  

Back to top
 
 
View Profile   IP Logged
Severino
YaBB Newbies
*
Offline

Build with me.

Posts: 43
Connecticut
Gender: male
Re: Touchpad Midi
Reply #4 - 13.02.2008 at 02:05:34
 
That is an awesome project!  What do you planning to do with this setup?
Back to top
 
 
View Profile | WWW   IP Logged
big93
Senior Member
****
Offline

Arduino rocks

Posts: 495

Re: Touchpad Midi
Reply #5 - 13.02.2008 at 02:47:39
 
wow, very nicely put together, looks very "CLEAN". My kind of "clean" is oversize drill holes, with a case way too big to be needed with 15 different battery packs... I gotta work on my enclosure skills...

either way, nice project, i hope you can develop this into a type of computer mouse, or music player.
Maybe it can have ipod touch like capabilities lol! good luck!
Back to top
 
 
View Profile   IP Logged
danreetz
YaBB Newbies
*
Offline

Arduino rocks

Posts: 6

Re: Touchpad Midi
Reply #6 - 18.02.2008 at 01:48:28
 
This is a beautifully executed project. Congratulations.

I'm trying to build a very similar device, though it is hard for me to understand all the code you've written. Hopefully with time, I'll understand it all. I would love to see any enhancements that you've made, as well as a few more comments. Wink

On the hardware side, I've been working on a couple different things that might be of interest to the community. One, I've found that Microsoft Optical mice are natively capable of PS2 -- it's only necessary to wire them differently to get them to turn on in PS2 mode. This opens up the possibility of using cheap and readily available optical mice with the Arduino. Below are two crude images describing the mouse and pinout. I've tried it on several generations of MS optical mice and it worked on all of them. I've never seen this pinout anywhere else.





Additionally, I had a VERY old laptop which had a touchpad in it. The touchpad pinout took some time to discover. Perhaps it will be useful for others, so here it is:



Back to top
 
 
View Profile   IP Logged
Sasha
YaBB Newbies
*
Offline

Arduino rocks

Posts: 1

Re: Touchpad Midi
Reply #7 - 19.02.2008 at 11:26:59
 
Hi everybody, I`ve seen this project on flickr (thanks ludo for directing me here) and thought it is very well done, looks great and it seams worth building it. Congratulations!
I got no programming skills, but as code is there I think I might give it try. As your touchpad is PS2, could this touchpad from Voti can be used?
It is very cheap surplus pad costs just 4.37EUR
http://www.voti.nl/shop/p/S-Touchpad.html


Are there any wiring details for this project?
Some youtube in action would be great to see. Smiley
Back to top
 
 
View Profile   IP Logged
nomuse
Junior Member
**
Offline

Arduino rocks

Posts: 78

Re: Touchpad Midi
Reply #8 - 26.02.2008 at 22:45:14
 
VERRY nice!  I also got into Arduino for the MIDI thing (but my aspirations were quite a bit lower).
Back to top
 
 
View Profile   IP Logged
marcel82
YaBB Newbies
*
Offline

Arduino rocks

Posts: 1

Re: Touchpad Midi
Reply #9 - 03.04.2008 at 01:09:59
 
Hi ludo

I'm trying to read out data from a Cirque 9920 touchpad.
I just saw on one of your photos, that you were using a similar type of touchpad...

What I am trying to do is to catch data from the finger position BEFORE I start moving it.
The regular PS/2 protocol gives you only delta values of the position. When I configure the pad to send automatically (stream mode) it only sends data, when a finger movement occurs.
In the (small) specification PDF for the touchpad, it sais something about an extended packet mode where I can get even the Z value (finger press). You have to change a hardware configurable option for that. On the back of the pad you find some connections you have to bridge to enable this options.
...I'm really hoping you (or someone else) know(s) what I am talking about and can give me some advice how to read out this data.

Thanks!
Marcel
Back to top
 
 
View Profile   IP Logged
Stigsi
YaBB Newbies
*
Offline

Arduino rocks

Posts: 1

Re: Touchpad Midi
Reply #10 - 09.06.2008 at 22:55:09
 
Wow! This is amazing! Grin
Back to top
 
 
View Profile   IP Logged
joerick
YaBB Newbies
*
Offline

Arduino rocks

Posts: 9

Re: Touchpad Midi
Reply #11 - 03.07.2008 at 00:27:38
 
Nice.
Am working on a similar project myself, however am running a synaptic trackpad in absolute mode, and then I can get XYZ (z is pressure) for 3 MIDI CCs. Will probably create a library for my own use (I like to keep messy hardware code separate), would anybody be interested in it?
Back to top
 
 
View Profile   IP Logged
bsom
YaBB Newbies
*
Offline

Arduino rocks

Posts: 2

Re: Touchpad Midi
Reply #12 - 09.07.2008 at 04:04:07
 
joerick wrote on 03.07.2008 at 00:27:38:
Nice.
Am working on a similar project myself, however am running a synaptic trackpad in absolute mode, and then I can get XYZ (z is pressure) for 3 MIDI CCs. Will probably create a library for my own use (I like to keep messy hardware code separate), would anybody be interested in it?


I am *absolutely* interested in your code, and which trackpad part number you used.  I'm also working on an enhanced version of this project, but absolute mode would be best for what I am doing (and Z could add an interesting wrinkle...)
Back to top
 
 
View Profile   IP Logged
joerick
YaBB Newbies
*
Offline

Arduino rocks

Posts: 9

Re: Touchpad Midi
Reply #13 - 09.07.2008 at 12:35:18
 
might see if i can get it packaged up today... i'm using a PS/2 synaptic trackpad, according to the synaptic interfacing guide i found on the internet, it's an 'Ultra-thin' TouchPad TM41Pxx220 (don't have it right here, not sure what the x's are!)

I think any PS/2 synaptic will work though.
Back to top
 
 
View Profile   IP Logged
joerick
YaBB Newbies
*
Offline

Arduino rocks

Posts: 9

Re: Touchpad Midi
Reply #14 - 17.07.2008 at 18:15:42
 
Ok, have got the code all wrapped up, would love if somebody could test? Don't know if it'll work with anything but the synaptic touchpads, unless it's all fairly standard protocol-wise...

http://www.arduino.cc/playground/Main/Trackpad

You need the PS2 library too.
http://www.arduino.cc/playground/ComponentLib/Ps2mouse

Let me know how you get on!
Back to top
 
 
View Profile   IP Logged
Pages: 1 2