Sample Programs

プレステコントローラの接続

プレイステーションコントローラーを使用する

回路図はコレ

本来はSPIのハードウエア機能で通信すると速く美しいのですが、まずは移植性も良いIOポート使用のプログラムになっています。

現在プレステコントローラは入手困難です。
ヴィストンで扱っていますロボットコントローラーVS-C1を使われてください。
以下ソースコードは動作確認済みなります。(基本プログラムがベースになっております。)

このソースは富山研究室の池田君から頂きました!感謝!

アナログモードで使用してください。
LCDに表示がでるようになっています。全てのボタンの情報が表示されるので確認できます。

追加******
下のソースを貼付けても上手く動かないという話を聞きますので、動くソースを丸ごとダンロードしてください。

PSCONプログラム

※[Release]モードでビルドしてください。
サーボはD1/D2/D3/D4で動く設定にしてあります。もっとたくさんのサーボを動かしたい場合は14サーボのプログラムに以下を貼付ければ大丈夫でしょう。
以下ソースでサーボが動かないのはDevInit_F2803x.cのピン設定がPWMになっていないからだと思われます。

ソースコード

#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
#include "NolibM.h"
#include <stdio.h>

#define PS_CON_DAT	GpioDataRegs.GPADAT.bit.GPIO12  /* 入力に設定 */
#define PS_CON_CMD	GpioDataRegs.GPADAT.bit.GPIO13  /* 出力に設定 */
#define PS_CON_SEL	GpioDataRegs.GPADAT.bit.GPIO27  /* 出力に設定 */
#define PS_CON_CLK	GpioDataRegs.GPADAT.bit.GPIO26  /* 出力に設定 */

#define ZERO_PM 10  /* ジョイスティックの不感帯の幅 */

volatile struct EPWM_REGS *ePWM[] =
 				  { &EPwm1Regs,			//intentional: (ePWM[0] not used)
				  	&EPwm1Regs,
					&EPwm2Regs,
					&EPwm3Regs,
					&EPwm4Regs,
					&EPwm5Regs,
					&EPwm6Regs,
					&EPwm7Regs,
				  };

/* コントローラの情報を収納する構造体の定義 */
struct PS_CMD{
	unsigned char dat[34];
	unsigned char length;
};

// These are defined by the linker (see F2808.cmd)
extern Uint16 RamfuncsLoadStart;
extern Uint16 RamfuncsLoadEnd;
extern Uint16 RamfuncsRunStart;

// Watch Viewでの値表示用にglobal変数として宣言
int16 speed;
Uint16 sen1,sen2,sen3,sen4;

// ボタン用の変数
unsigned char ll ,dd, rr, uu; // 左、下、右、上
unsigned char st, R3, L3, se; // スタート、右ジョイスティックスイッチ、左ジョイスティックスイッチ、セレクト
unsigned char ss, xx, cc, tt; // しかく、ばつ、まる、さんかく
unsigned char R1, L1, R2, L2; // R1、L1、R2、L2
char right_ud, right_lr; // 右ハンドル上下、右ハンドル左右
char left_ud, left_lr; // 左ハンドル上下、左ハンドル左右

/********************************
 * プレステ用コントローラの状態の読み取り
 *******************************/
 #define SPI_DELAY 400

void pscon_read(struct PS_CMD *psmd)
{
	int i,j;
	for(i=0;i<35;i++){ //配列ゼロ初期化
		psmd->dat[i] = 0;
	}
    PS_CON_SEL = 1;
    DSP28x_usDelay(SPI_DELAY);
	PS_CON_SEL = 0;
	DSP28x_usDelay(SPI_DELAY);

	PS_CON_CLK = 1;
	PS_CON_CMD = 0;
	DSP28x_usDelay(SPI_DELAY);

	for(i=0; i<8; i++){  //1バイト目コマンドを送る 0x01
		PS_CON_CLK = 1;
		DSP28x_usDelay(SPI_DELAY);
		PS_CON_CMD = (0x01 >> i) & 0x01;
	//	DSP28x_usDelay(SPI_DELAY);
		PS_CON_CLK = 0;
		DSP28x_usDelay(SPI_DELAY);
	}

		DSP28x_usDelay(2*SPI_DELAY);  //------

	for(i=0; i<8; i++){ //2バイト目コマンドを送る 0x42
		PS_CON_CLK = 1;
//		DSP28x_usDelay(SPI_DELAY);
		PS_CON_CMD = (0x42 >> i) & 0x01;
		DSP28x_usDelay(SPI_DELAY);
		PS_CON_CLK = 0;
		DSP28x_usDelay(SPI_DELAY);
		psmd->dat[0] |= (PS_CON_DAT & 0x01) <<  i;  //データを読み込む
	}
	psmd->length = (0x0F & psmd->dat[0])*2;
	if(psmd->length > 32){
		psmd->length = 32;
	}
	if(psmd->length == 0){
		psmd->length = 32;
	}
	DSP28x_usDelay(2*SPI_DELAY);
	for(i=0; i<8; i++){  //3バイト目コマンド0x00
		PS_CON_CLK = 1;
		DSP28x_usDelay(SPI_DELAY);
		PS_CON_CMD = 0;
		PS_CON_CLK = 0;
		DSP28x_usDelay(SPI_DELAY);
		psmd->dat[1] |= (PS_CON_DAT & 0x01) <<  i;  //データ読み込み
	}
	PS_CON_CLK = 1;
	DSP28x_usDelay(SPI_DELAY);

	for(i=0; i<psmd->length; i++){ //種類によって読み込む情報量が違う
		psmd->dat[i+2] = 0;
		for(j=0; j<8; j++){
			PS_CON_CLK = 1;
			DSP28x_usDelay(SPI_DELAY);
			PS_CON_CLK = 0;
			DSP28x_usDelay(SPI_DELAY);
			psmd->dat[i+2] |= (PS_CON_DAT & 0x01) << j;
		}
	}
	PS_CON_CLK = 1;
	DSP28x_usDelay(SPI_DELAY);
	PS_CON_SEL = 1;
		//DSP28x_usDelay(10000); //------
}

void main(void)
{
	int i;
	int cnt;
	int right_spd, left_spd;
	struct PS_CMD sts;
    char msg1[16],msg2[16];

	initNolibM(); //初期化

	GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 0;	// 0=GPIO,  1=TZ1,  2=SCITX-A,  3=SPISIMO-B
	GpioCtrlRegs.GPADIR.bit.GPIO12 = 0;		// 1=OUTput,  0=INput
	GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 0;	// 0=GPIO,  1=TZ2,  2=Resv,  3=SPISOMI-B
	GpioCtrlRegs.GPADIR.bit.GPIO13 = 1;		// 1=OUTput,  0=INput
	GpioCtrlRegs.GPAMUX2.bit.GPIO26 = 0;	// 0=GPIO,  1=Resv,  2=Resv,  3=SPICLK-B
	GpioCtrlRegs.GPADIR.bit.GPIO26 = 1;		// 1=OUTput,  0=INput
	GpioCtrlRegs.GPAMUX2.bit.GPIO27 = 0;	// 0=GPIO,  1=Resv,  2=Resv,  3=SPISTE-B
	GpioCtrlRegs.GPADIR.bit.GPIO27 = 1;		// 1=OUTput,  0=INput

	motor(0, MotCN3);
	motor(0, MotCN4);
	motor(0, MotCN5);
	motor(0, MotCN6);
	wait(10);

	ledFlash(OFF,1);
	ledFlash(OFF,2);
	ledFlash(OFF,3);
	ledFlash(OFF,4);
	cnt = 1;
	for(i=0;i<34;i++){
		sts.dat[i] = 0;
	}
	right_ud = 0;
	left_ud = 0;

	while(1)
	{

		pscon_read(&sts);  // コントローラの状態を読み取る

		// コントローラの情報をLCDに表示
	    sprintf(msg1,"%02x %02x %02x %02x  %2d",sts.dat[0], sts.dat[1], sts.dat[2], sts.dat[3], sts.length);
		sprintf(msg2,"%02x %02x %02x %02x  %1d",sts.dat[4], sts.dat[5], sts.dat[6], sts.dat[7], cnt);
		lcd_HOME();//カーソルをホームへ
   		lcd_PUTS((unsigned char *)msg1);
   		lcd_LF();
   		lcd_PUTS((unsigned char *)msg2);
   		// 読取データをそれぞれの変数に分割
   		if(sts.dat[1] == 0x5a){
	   		if(sts.length >= 2){
	   			ll = (0x80 & ~sts.dat[2]) >> 7;
	   			dd = (0x40 & ~sts.dat[2]) >> 6;
	   			rr = (0x20 & ~sts.dat[2]) >> 5;
	   			uu = (0x10 & ~sts.dat[2]) >> 4;
	   			st = (0x08 & ~sts.dat[2]) >> 3;
	   			R3 = (0x04 & ~sts.dat[2]) >> 2;
	   			L3 = (0x02 & ~sts.dat[2]) >> 1;
	   			se = (0x01 & ~sts.dat[2]);
	   			ss = (0x80 & ~sts.dat[3]) >> 7;
	   			xx = (0x40 & ~sts.dat[3]) >> 6;
	   			cc = (0x20 & ~sts.dat[3]) >> 5;
	   			tt = (0x10 & ~sts.dat[3]) >> 4;
	   			R1 = (0x08 & ~sts.dat[3]) >> 3;
	   			L1 = (0x04 & ~sts.dat[3]) >> 2;
	   			R2 = (0x02 & ~sts.dat[3]) >> 1;
	   			L2 = (0x01 & ~sts.dat[3]);
	   		}
	   		if(sts.length >= 6){
	   			// 不感帯の設定
	   			for(i=0; i<4; i++){
	   				if((0x80 - ZERO_PM) < sts.dat[4+i] && sts.dat[4+i] < (0x80 + ZERO_PM)){
		   				sts.dat[4+i] = 0x80;
	   				}
	   			}
	   			right_lr = sts.dat[4] - 0x80;  // 左がマイナス -128 ~ +127
	   			right_ud = sts.dat[5] - 0x80;  // 上がマイナス -128 ~ +127
	   			left_lr = sts.dat[6] - 0x80;  // 左がマイナス -128 ~ +127
	   			left_ud = sts.dat[7] - 0x80;  // 上がマイナス -128 ~ +127
	   		}
   		}
   		// 分割終わり

   		if(L2 == 1){
	   		right_spd = right_ud * 35 / 128;
   			left_spd = left_ud * 35 / 128;
   		}else if(R2 == 1){
	   		right_spd = right_ud * 100 / 128;
   			left_spd = left_ud * 100 / 128;
   		}else{
	   		right_spd = right_ud * 70 / 128;
   			left_spd = left_ud * 70 / 128;
   		}

   		motor(right_spd, MotCN3);
   		motor(left_spd, MotCN5);

		wait(100);

		// 動作確認用にLEDを順次点滅
		if(cnt==1){
			ledFlash(TOGGLE,1);
		}else if(cnt == 2){
			ledFlash(TOGGLE,2);
		}else if(cnt == 3){
			ledFlash(TOGGLE,3);
		}else{
			ledFlash(TOGGLE,4);
			cnt = 0;
		}
		cnt++;
	} // 無限ループ終わり
}
Follow Me!
  • Twitter