!gEDA
Linuxで回路図を書こうとして探してたらこれを発見

>>
# aptitude install geda-gschem
<<
でインストール(Debian)

http://www.mail-archive.com/geda-user@moria.seul.org/msg17056.html
ここからatmega168のデータを借りてくる
シンボルの作成は
http://www5a.biglobe.ne.jp/~nkgwtty/njaLinuxgEDA01.html#SYM_MK を参考にした。


とりあえず回路図: http://inajob.no-ip.org/dev/rakuchord_mobile/keykey.png

なんかうまく使いこなせてない感。とりあえず書いてみた。
画像書き出しの範囲指定がなんか微妙で上切れちゃった(スクロール位置と関係がある?)

CON1は後から書きこむ用のピンです。動作には使いません。
あとPS/2の配線は書いてないですが5番がCLK、6番がDATA

!!ソース
取り回しの関係でコメントが謎英語になってます。
breakってのはキーアップのことです。
PROGMEM使うつもりで使ってないのも あとで直す って思っててそのまま放置した跡です。

見苦しい点は少しずつ直していきます。

キーボードの周りはhttp://www.arduino.cc/playground/Main/PS2Keyboard このへん参考にした

!!!あれ? 直したい!
- 1<<14 がなんで出てきたのか不明。まぁ周波数は合ってるから音はでるけど変な波形になる気が…?
- 普通に↑のライブラリを使ったほうがよさげ。 スキャンコードとASCIIの対応表とかパターン多そうだし…


>>
#define PS2_KC_BREAK  0xf0
#define PS2_KC_ENTER  0x5a
#define PS2_KC_ESC    0x76
#define PS2_KC_KPLUS  0x79
#define PS2_KC_KMINUS 0x7b
#define PS2_KC_KMULTI 0x7c
#define PS2_KC_NUM    0x77
#define PS2_KC_BKSP   0x66

#define PS2_INT_PIN 3

class PS2Keyboard {
  private:
    int  m_dataPin;
    byte m_charBuffer;
  
  public:
    PS2Keyboard();
    void begin(int dataPin);
    bool available();
    bool available2();
    byte read();
    byte read2();
};

#include <avr/pgmspace.h>

#define PS2_KC_LUT_CAPACITY 56

//PROGMEM 
prog_uchar PS2_KC_LUT_DATA[PS2_KC_LUT_CAPACITY] = {0x70, 0x69, 0x72, 0x7a, 0x6b, 0x73, 0x74, 0x6c, 0x75, 0x7d, 0x15,0x16,0x1A,0x1B,0x1C,0x1D,0x1E,0x21,0x22,0x23,0x24,0x25,0x26,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x31,0x32,0x33,0x34,0x35,0x36,0x3A,0x3B,0x3C,0x3D,0x3E,0x42,0x43,0x44,0x45,0x46,0x4B,0x4D,
0x4c,0x52,0x41,0x49,0x4A  ,0x54,0x5B,0x5d,
0x66 // BS
};
//PROGMEM
prog_uchar PS2_KC_LUT_CHAR[PS2_KC_LUT_CAPACITY] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9','Q','1','Z','S','A','W','2','C','X','D','E','4','3',' ','V','F','T','R','5','N','B','H','G','Y','6','M','J','U','7','8','K','I','O','0','9','L','P',
';',':',',','.','\\','@','[',']',
0x08 // BS
};

int ps2Keyboard_DataPin;
volatile byte ps2Keyboard_CurrentBuffer;
volatile byte ps2Keyboard_CharBuffer;
volatile byte ps2Keyboard_CharBuffer2; // for break
volatile byte ps2Keyboard_BufferPos;
volatile bool ps2Keyboard_BreakActive;

volatile bool value;
volatile bool value2;    // for break

volatile bool ring[128]; // 2^7 ring buffer
volatile unsigned char ringc = 0; // current write position
volatile unsigned char ringr = 0; // current read position


// The ISR for the external interrupt
ISR(INT1_vect) {  
  value = (PIND&(0b00010000))?1:0;//digitalRead(ps2Keyboard_DataPin);
  ring[ringc] = value;
  ringc = (ringc + 1) & 0b1111111;
}

PS2Keyboard::PS2Keyboard() {
  // nothing to do here	
}

void PS2Keyboard::begin(int dataPin) {
  // Prepare the global variables
  ps2Keyboard_DataPin = dataPin;
  ps2Keyboard_CurrentBuffer = 0;
  ps2Keyboard_CharBuffer = 0;
  ps2Keyboard_BufferPos = 0;
  ps2Keyboard_BreakActive = false;

  // initialize the pins
  pinMode(PS2_INT_PIN, INPUT);
  digitalWrite(PS2_INT_PIN, HIGH); // pull up mode
  pinMode(PS2_INT_PIN, OUTPUT);
  digitalWrite(PS2_INT_PIN, HIGH);
  pinMode(dataPin, INPUT);
  digitalWrite(dataPin, HIGH);    // pull up mode
  
  // Global Enable INT1 interrupt
  EIMSK |= ( 1 << INT1);
  // Falling edge triggers interrupt
  EICRA |= (0 << ISC10) | (1 << ISC11);
}

bool PS2Keyboard::available() {
  return ps2Keyboard_CharBuffer != 0;
}

bool PS2Keyboard::available2() {
  return ps2Keyboard_CharBuffer2 != 0;
}

byte PS2Keyboard::read() {
  byte result = ps2Keyboard_CharBuffer;
  for(int i = 0; i < PS2_KC_LUT_CAPACITY; i++) {
    if(ps2Keyboard_CharBuffer == /*pgm_read_byte_near*/(PS2_KC_LUT_DATA[i]/* + i*/)) {

      result = /*pgm_read_byte_near*/(PS2_KC_LUT_CHAR[i]/* + i*/);
    }
  }
  ps2Keyboard_CharBuffer = 0;
  
  return result;
}

byte PS2Keyboard::read2() {
  byte result = ps2Keyboard_CharBuffer2;
  for(int i = 0; i < PS2_KC_LUT_CAPACITY; i++) {
    if(ps2Keyboard_CharBuffer2 == /*pgm_read_byte_near*/(PS2_KC_LUT_DATA[i]/* + i*/)) {

      result = /*pgm_read_byte_near*/(PS2_KC_LUT_CHAR[i]/* + i*/);
    }
  }
  ps2Keyboard_CharBuffer2 = 0;
  
  return result;
}


const int DataPin = 4;
const int IRQpin =  3;

const int speakerPin = 9;

const unsigned int timerLoadValue = 254;

volatile unsigned char level = 0;
volatile unsigned int d[5] = {80,260,330,390,520}; // default value( for debug)
const unsigned int tones[] = {95,106,123,127,145,160,179,190
                          ,212,246,254,290,320,358,380};
volatile unsigned int dn[5] = {0,0,0,0,0};       // work variable

volatile unsigned char vol[5] = {32,16,16,16,16}; // volume par channel

volatile unsigned int counter = 0;
volatile unsigned char bend = 0;
ISR(TIMER2_OVF_vect) {    // Timer/Counter2 Overflow
  TCNT2 = timerLoadValue; // Reset the timer
  dn[0] = dn[0] + d[0] + bend;
  dn[1] = dn[1] + d[1] + bend;
  dn[2] = dn[2] + d[2] + bend;
  dn[3] = dn[3] + d[3] + bend;
  dn[4] = dn[4] + d[4] + bend;
    
  //chord composite
  level = ((dn[0]&(1<<14))?vol[0]:0) +
          ((dn[1]&(1<<14))?vol[1]:0) +
          ((dn[2]&(1<<14))?vol[2]:0) +
          ((dn[3]&(1<<14))?vol[3]:0) +
          ((dn[4]&(1<<14))?vol[4]:0);
  OCR1A = level;
}

PS2Keyboard keyboard;

void setup() {
  delay(1000);
  keyboard.begin(DataPin);
  Serial.begin(9600);
  Serial.println("Keyboard Test:");
  
  pinMode(speakerPin, OUTPUT);

  TCCR1A = _BV(COM2A1) | _BV(COM2B1)| _BV(WGM20);
  TCCR1B = _BV(CS22) | _BV(WGM12) | _BV(WGM13);
  OCR1A = 180; // for debug
  //OCR1B = 50;
  
  TCCR1B = TCCR1B & 0b11100000 | 0b00001; // pwm: 31250Hz
  
  TCCR2A = 0; // Normal Timer
  TCCR2B = 1<<CS22 | 0<<CS21 | 1<<CS20; // clk/128 prescale
  TIMSK2 = 1<<TOIE2; // Timer/Counter2 Overflow Interrupt Enable
  TCNT2 = timerLoadValue;
}

unsigned int rythm[8] = {0,0,0,0,0,0,0,0};
char rythmSel = -1;
char rythmStep = 0;
char rythmCount = 0;
char rythmMode = 0;

void loop() {
  bend = analogRead(0) >> 2;
  counter ++;
  if(counter & (1 << 8)){
    counter = 0;
    if(vol[0] > 0)vol[0]--; // volume down
    if(rythmMode){ // step sequencer mode?
    rythmCount ++;
    if(rythmCount & (1<<2)){
      rythmCount = 0;
      rythmStep = (rythmStep + 1) & 0b111;
      dn[4] = 0;
      d[4] = rythm[rythmStep];
    }
    }
  }
    
  if (keyboard.available2()) { // for break
    char c = keyboard.read2();
    switch(c){
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      rythmSel = -1;
      Serial.println("[break]");
    }
  }  
  
  if (keyboard.available()) {
    // read the next key
    char c = keyboard.read();
    {
      // otherwise, just print all normal characters
      Serial.print(c);
      switch(c){
        case PS2_KC_ESC:
          d[0] = d[1] = d[2] = d[3] = d[4] = 0;
          break;
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
         rythmSel = c - '1';
         break;
        case '0':
          rythmMode = !rythmMode;
        default:
          char tmp = c2c(c);
          
          if(tmp < 19 && tmp>=0){
            if(rythmSel != -1){
                rythm[rythmSel] = tones[tmp];
            }else{
              d[0] = (tones[tmp]<<0);
              vol[0] = 32;
            }
          }
          if(tmp >=19 && tmp <=31){
            dn[1] = dn[2] = dn[3] = 0;
          d[1] = (tones[tmp - 19]<<0);
          d[2] = (tones[tmp - 19 + 2]<<0);
          d[3] = (tones[tmp - 19 + 4]<<0);
          }
      }
    }
  }

  //===================
  if(ringr != ringc){
      value2 = ring[ringr];
      ringr = (ringr + 1) & 0b1111111;
      if(ps2Keyboard_BufferPos==0){
        if(value2!=0){
          ps2Keyboard_BufferPos = 0;
          ps2Keyboard_CurrentBuffer = 0;
          ps2Keyboard_CharBuffer = 0;
          ps2Keyboard_BreakActive = false;
          return;
        }
      }
      if(ps2Keyboard_BufferPos > 0 && ps2Keyboard_BufferPos < 9) {
        ps2Keyboard_CurrentBuffer |= (value2 << (ps2Keyboard_BufferPos - 1));
      }
      ps2Keyboard_BufferPos++;
      
      if(ps2Keyboard_BufferPos == 11) {
        if(ps2Keyboard_CurrentBuffer == PS2_KC_BREAK) {
          ps2Keyboard_BreakActive = true;
        } else if(ps2Keyboard_BreakActive) {
          ps2Keyboard_BreakActive = false;
          Serial.print("break:");
          Serial.println(ps2Keyboard_CurrentBuffer,HEX);
          
          ps2Keyboard_CharBuffer2 = ps2Keyboard_CurrentBuffer;
        } else {
          Serial.print("input:");
          Serial.println(ps2Keyboard_CurrentBuffer,HEX);
  
          ps2Keyboard_CharBuffer = ps2Keyboard_CurrentBuffer;
        }
        ps2Keyboard_CurrentBuffer = 0;
        ps2Keyboard_BufferPos = 0;
      }
    }
    //===================
}

int c2c(char c){
  switch(c){
    case 'A': return 0;
    case 'S': return 1;
    case 'D': return 2;
    case 'F': return 3;
    case 'G': return 4;
    case 'H': return 5;
    case 'J': return 6;
    case 'K': return 7;
    
    case 'L': return 8;
    case ';': return 9;
    case ':': return 10;
    
    case 'Z': return 7;
    case 'X': return 8;
    case 'C': return 9;
    case 'V': return 10;
    case 'B': return 11;
    case 'N': return 12;
    case 'M': return 13;
    case ',': return 14;
    case '.': return 15;
    case '?': return 16;
    case '\\': return 17;
    
    case 'Q': return 19;
    case 'W': return 20;
    case 'E': return 21;
    case 'R': return 22;
    case 'T': return 23;
    case 'Y': return 24;
    case 'U': return 25;
    case 'I': return 26;
    case 'O': return 27;
    case 'P': return 28;
    case '@': return 29;
    case '[': return 30;
    case ']': return 31;
  }
  return -1;
}
<<
5643382
wiki
1323187463