PS2のコントローラを繋ぎたかったのだが、Arduino用のサンプルのみで敷居が高かった。
アナログ部分は使わないので、”ピコーン!”と閃いた。スーパーファミコンのコントローラならもっと簡単じゃね?と。
で、検索してみるとサンプルっぽいもの。さらに、Arduinoに繋ぐlibraryがとても簡潔でわかりやすい。
ので、ハードオフにてドナーとなるコントローラをゲット。1つ105円。
ジャンク本体でもあれば尚良かったのだが、それは無かった。もう扱ってないのだろうか。(ジャンクじゃ無いモノはあった)
さっそくコネクタ部分をばらしてみると、7pinありそうなコネクタだったが、実際は5pin。
電源とGND、その他3pin。Arduinoに繋いで動作確認。問題無し。電源を3.3Vにしてみたが、これも問題無し。
搭載チップMC14021のデータシートでも問題なさそうだった。
電源はraspiの3.3Vから取得。ササササッとコードを書いて、raspiでの動作も確認。
以下ソース
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <signal.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#define PIN_DATA RPI_V2_GPIO_P1_13 //Red
#define PIN_CLOCK RPI_V2_GPIO_P1_11 //Yellow
#define PIN_LATCH RPI_V2_GPIO_P1_15 //Orange
//Brown = Ground
//White = VCC
#define SFCPAD_B_BTN 0x0001
#define SFCPAD_Y_BTN 0x0002
#define SFCPAD_SELECT 0x0004
#define SFCPAD_START 0x0008
#define SFCPAD_UP 0x0010
#define SFCPAD_DOWN 0x0020
#define SFCPAD_LEFT 0x0040
#define SFCPAD_RIGHT 0x0080
#define SFCPAD_A_BTN 0x0100
#define SFCPAD_X_BTN 0x0200
#define SFCPAD_L_BTN 0x0400
#define SFCPAD_R_BTN 0x0800
uint16_t readsfcpad() {
int i;
uint16_t b;
uint16_t d;
uint8_t dataval;
b = 1;
d = 0;
dataval = 1;
bcm2835_gpio_write(PIN_LATCH,LOW);
usleep(250);
for (i = 0;i < 16;i++ ){
dataval = bcm2835_gpio_lev(PIN_DATA);
//printf("dataval:%d \n",dataval);
if ( dataval == 0 ) {
d = d | b;
}
b = b<<1;
bcm2835_gpio_write(PIN_CLOCK,HIGH);
usleep(500);
bcm2835_gpio_write(PIN_CLOCK,LOW);
}
bcm2835_gpio_write(PIN_LATCH,HIGH);
return d;
}
int main(int argc,char **argv)
{
//GPIOを初期化
if (!bcm2835_init()) {
printf("bcm2835 init error.\n");
exit(1);
}
//PINの設定
bcm2835_gpio_fsel(PIN_DATA ,BCM2835_GPIO_FSEL_INPT);
bcm2835_gpio_fsel(PIN_CLOCK,BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel(PIN_LATCH,BCM2835_GPIO_FSEL_OUTP);
//VCCまでプルアップ
bcm2835_gpio_set_pud(PIN_DATA,BCM2835_GPIO_PUD_UP);
//SFC_PAD との通信初期化
bcm2835_gpio_write(PIN_CLOCK,LOW);
bcm2835_gpio_write(PIN_LATCH,HIGH);
uint16_t rd;
while(1) {
//ボタンの状態を読み、
rd = readsfcpad();
if (rd != 0) {
//ビット演算により、ボタンが押されているか
if ( (rd & SFCPAD_B_BTN ) == SFCPAD_B_BTN) { printf("B\n"); }
if ( (rd & SFCPAD_Y_BTN ) == SFCPAD_Y_BTN) { printf("Y\n"); }
if ( (rd & SFCPAD_SELECT) == SFCPAD_SELECT) { printf("Sel\n"); }
if ( (rd & SFCPAD_START ) == SFCPAD_START) { printf("Sta\n"); }
if ( (rd & SFCPAD_UP ) == SFCPAD_UP ) { printf("UP\n"); }
if ( (rd & SFCPAD_DOWN ) == SFCPAD_DOWN) { printf("Do\n"); }
if ( (rd & SFCPAD_LEFT ) == SFCPAD_LEFT) { printf("Le\n"); }
if ( (rd & SFCPAD_RIGHT ) == SFCPAD_RIGHT) { printf("Ri\n"); }
if ( (rd & SFCPAD_A_BTN ) == SFCPAD_A_BTN) { printf("A\n"); }
if ( (rd & SFCPAD_X_BTN ) == SFCPAD_X_BTN) { printf("X\n"); }
if ( (rd & SFCPAD_L_BTN ) == SFCPAD_L_BTN) { printf("L\n"); }
if ( (rd & SFCPAD_R_BTN ) == SFCPAD_R_BTN) { printf("R\n"); }
}
}
} |
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <signal.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#define PIN_DATA RPI_V2_GPIO_P1_13 //Red
#define PIN_CLOCK RPI_V2_GPIO_P1_11 //Yellow
#define PIN_LATCH RPI_V2_GPIO_P1_15 //Orange
//Brown = Ground
//White = VCC
#define SFCPAD_B_BTN 0x0001
#define SFCPAD_Y_BTN 0x0002
#define SFCPAD_SELECT 0x0004
#define SFCPAD_START 0x0008
#define SFCPAD_UP 0x0010
#define SFCPAD_DOWN 0x0020
#define SFCPAD_LEFT 0x0040
#define SFCPAD_RIGHT 0x0080
#define SFCPAD_A_BTN 0x0100
#define SFCPAD_X_BTN 0x0200
#define SFCPAD_L_BTN 0x0400
#define SFCPAD_R_BTN 0x0800
uint16_t readsfcpad() {
int i;
uint16_t b;
uint16_t d;
uint8_t dataval;
b = 1;
d = 0;
dataval = 1;
bcm2835_gpio_write(PIN_LATCH,LOW);
usleep(250);
for (i = 0;i < 16;i++ ){
dataval = bcm2835_gpio_lev(PIN_DATA);
//printf("dataval:%d \n",dataval);
if ( dataval == 0 ) {
d = d | b;
}
b = b<<1;
bcm2835_gpio_write(PIN_CLOCK,HIGH);
usleep(500);
bcm2835_gpio_write(PIN_CLOCK,LOW);
}
bcm2835_gpio_write(PIN_LATCH,HIGH);
return d;
}
int main(int argc,char **argv)
{
//GPIOを初期化
if (!bcm2835_init()) {
printf("bcm2835 init error.\n");
exit(1);
}
//PINの設定
bcm2835_gpio_fsel(PIN_DATA ,BCM2835_GPIO_FSEL_INPT);
bcm2835_gpio_fsel(PIN_CLOCK,BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel(PIN_LATCH,BCM2835_GPIO_FSEL_OUTP);
//VCCまでプルアップ
bcm2835_gpio_set_pud(PIN_DATA,BCM2835_GPIO_PUD_UP);
//SFC_PAD との通信初期化
bcm2835_gpio_write(PIN_CLOCK,LOW);
bcm2835_gpio_write(PIN_LATCH,HIGH);
uint16_t rd;
while(1) {
//ボタンの状態を読み、
rd = readsfcpad();
if (rd != 0) {
//ビット演算により、ボタンが押されているか
if ( (rd & SFCPAD_B_BTN ) == SFCPAD_B_BTN) { printf("B\n"); }
if ( (rd & SFCPAD_Y_BTN ) == SFCPAD_Y_BTN) { printf("Y\n"); }
if ( (rd & SFCPAD_SELECT) == SFCPAD_SELECT) { printf("Sel\n"); }
if ( (rd & SFCPAD_START ) == SFCPAD_START) { printf("Sta\n"); }
if ( (rd & SFCPAD_UP ) == SFCPAD_UP ) { printf("UP\n"); }
if ( (rd & SFCPAD_DOWN ) == SFCPAD_DOWN) { printf("Do\n"); }
if ( (rd & SFCPAD_LEFT ) == SFCPAD_LEFT) { printf("Le\n"); }
if ( (rd & SFCPAD_RIGHT ) == SFCPAD_RIGHT) { printf("Ri\n"); }
if ( (rd & SFCPAD_A_BTN ) == SFCPAD_A_BTN) { printf("A\n"); }
if ( (rd & SFCPAD_X_BTN ) == SFCPAD_X_BTN) { printf("X\n"); }
if ( (rd & SFCPAD_L_BTN ) == SFCPAD_L_BTN) { printf("L\n"); }
if ( (rd & SFCPAD_R_BTN ) == SFCPAD_R_BTN) { printf("R\n"); }
}
}
}