elechobby:picdic:pic12f683:16

電子サイコロ

いろいろなゲームに使われる、サイコロ(ダイス)を、出来るだけ小さくを目標に、8ピンのPICで実現してみました。

8ピンのPICでは、I/O数の制約(電源を除くと6個)が大きいので、当初サイコロには向かないのではと考えました。

  • LEDが6個
  • スタートスイッチが1個
  • ブザーが1個

このように8個のI/Oが必要となり、2個足りません。18ピンのPICなら、何も問題はないのですが。。。

そこで、次のように考えてみました。

  • サイコロの1~6迄の目を重ね合わせてみると、図2のように7個のLEDで表現することができます。
  • そして7個のLEDを4つのグループに分類します。
  • * (A)→1個
  • * (B)→2個
  • * (C)→2個
  • * (D)→2個
  • サイコロの目とLEDの関係を次のようにします。
  • 1→(A)
  • 2→(B)
  • 3→(A)(B)
  • 4→(B)(C)
  • 5→(A)(B)(C)
  • 6→(B)(C)(D)

このようにすることで、LED部分は、4個のI/Oで足りることになります。

※この考え方は、電子マスカットさんの「青い電子サイコロ」を参考にしました。

<プログラム上の工夫>

  • mikroCには、乱数に関する関数が用意されています。
    rand関数→擬似乱数を発生させます。
    srand関数→rand関数で発生させる擬似乱数の発生系列を変更します。
  • rand関数は、同じ繰返しで擬似乱数を発生させるので、起動し直しても、毎回同じパターンの乱数値に
    なってしまい、利用者に覚えられてしまいます。
  • そこで、起動時に、srand関数で発生系列を変更するようにしました。その時の系列値は、タイマー割り込み
    で常にインクリメントしている変数を用います。系列を変更するタイミングは、利用者がプッシュスイッチを押
    した時としましたので、どの系列になるかは不定です。こうすることによって、起動し直しても系列が異なる
    ので利用者に覚えられることがありません。
  • プッシュスイッチを押して、直ぐに結果が出るのでは面白くありませんので、徐々に速度を落としながら結果
    が出るようにしました。
  • また、LEDの点灯だけでは、寂しいので、PWMによるブザー音も発生させました。
dice.c
//********************************************************************** 
 
#define		LED_A		GPIO.F0
#define		LED_B		GPIO.F1
#define		LED_C		GPIO.F4
#define		LED_D		GPIO.F5
 
#define		SW			GPIO.F3
 
#define		ON			0
#define		OFF			1
 
//********************************************************************** 
 
static	unsigned	int		seed;
 
void	interrupt(){
	if (INTCON.T0IF == 1) {
		INTCON.T0IF = 0;
		//
		seed++;
	}
}
 
//********************************************************************** 
 
void	Pwm_Change_DutyEx(unsigned int duty_ratio)
{
    CCPR1L = duty_ratio >> 2;
    CCP1CON.F6 = duty_ratio & 0b00000001;
    CCP1CON.F7 = (duty_ratio & 0b00000010) >> 1; 
}
 
//********************************************************************** 
 
void	diceChange()
{
	int		tmp;
	//
	tmp = rand();
	tmp = (((double)tmp) / 32768.0) * 6.0;
	//
	switch (tmp + 1) {
	case 1:
		LED_A = ON;
		LED_B = OFF;
		LED_C = OFF;
		LED_D = OFF;
		break;
	case 2:
		LED_A = OFF;
		LED_B = ON;
		LED_C = OFF;
		LED_D = OFF;
		break;
	case 3:
		LED_A = ON;
		LED_B = ON;
		LED_C = OFF;
		LED_D = OFF;
		break;
	case 4:
		LED_A = OFF;
		LED_B = ON;
		LED_C = ON;
		LED_D = OFF;
		break;
	case 5:
		LED_A = ON;
		LED_B = ON;
		LED_C = ON;
		LED_D = OFF;
		break;
	case 6:
		LED_A = OFF;
		LED_B = ON;
		LED_C = ON;
		LED_D = ON;
		break;
	}
}
 
//********************************************************************** 
 
void main()
{
	char	cnt;
	//
	OSCCON = 0b01111000;	// クロックは8Mhz 
	CMCON0 = 0b00000111;	// コンパレータは使用しない。 
	ANSEL  = 0b00000000;	// A/D変換を使用しない。 
	TRISIO = 0b00001000;
	//TIMER0の設定 
	INTCON.T0IE = 1;
	INTCON.T0IF = 0;
	OPTION_REG.T0CS = 0;
	OPTION_REG.PSA = 0;
	OPTION_REG.PS0 = 0;
	OPTION_REG.PS1 = 0;
	OPTION_REG.PS2 = 0;
	//
	Pwm_Init(1200);
	Pwm_Change_DutyEx((PR2 * 4) / 2);
	//
	LED_A = OFF;
	LED_B = OFF;
	LED_C = OFF;
	LED_D = OFF;
	//
	INTCON.PEIE = 1;	// これ以降の処理で割り込みを許可する。 
	INTCON.GIE = 1;		// これ以降の処理で割り込みを許可する。 
	//スイッチが押されるまで、LEDの点滅を繰り返す。 
	while (SW == OFF) {
		LED_A = ON;
		LED_B = ON;
		LED_C = ON;
		LED_D = ON;
		Delay_ms(100);
		LED_A = OFF;
		LED_B = OFF;
		LED_C = OFF;
		LED_D = OFF;
		Delay_ms(100);
	}
	//スイッチが離されるのを待つ。 
	while (SW == ON) {
		Delay_ms(100);
	}
	//ブザー音を鳴らす。 
	Pwm_Start();
	Delay_ms(200);	
	Pwm_Stop();
	//乱数の種をセットする。 
	srand(seed);
	//
	while (1) {
		//スイッチが押されるまで待つ。 
		if (SW == OFF) {
			Delay_ms(10);
			continue;
		}
		//サイコロの目を切り替える。 
		for (cnt = 0; cnt < 30; cnt++) {
			diceChange();
			//ブザー音を鳴らす。 
			Pwm_Start();
			Delay_ms(100);	
			Pwm_Stop();
			//可変型スリープ 
			Vdelay_ms(50 + (cnt * 10));
		}
	}
}
 
//**********************************************************************

ブレッドボードで確認したので、LEDをサイコロの目のように並べていません。
基板等に組み込むときには、並べてください。
向かって左から、(A)(B)(B)(C)(C)(D)(D)の順になります。
右上の大きい丸状のものは、圧電スピーカです。
右下のプッシュスイッチは、スタート用のものです。

起動時には、全LEDが点滅しますので、この間にプッシュスイッチを押してください。
そうすることにより擬似乱数の発生系列が変更されます。

サイコロの目が1~6の時の、LEDの点灯パターンです。


如何ですか?
これを2セット用意するとゲームの幅が広がるかもしれませんね。^_^

著作権表示 copyright notice

このページは稲崎様の閉鎖したHPのコピーで、著作権は稲崎様にあります。詳細
This page is a copy of Mr. Inasaki's closed website, and the copyright is held by him.Details
  • elechobby/picdic/pic12f683/16.txt
  • 最終更新: 2025/10/17 14:29
  • by 127.0.0.1