====== 電子サイコロ ======
===== 概要 =====
いろいろなゲームに使われる、サイコロ(ダイス)を、出来るだけ小さくを目標に、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で足りることになります。
※この考え方は、電子マスカットさんの「[[https://www.zea.jp/audio/dice/dice_01.htm|青い電子サイコロ]]」を参考にしました。
===== 回路図 =====
{{:imgpaste:202004:htmikan-20200428-182716.png}}
===== ソースコード =====
<プログラム上の工夫>
* mikroCには、乱数に関する関数が用意されています。\\ rand関数→擬似乱数を発生させます。\\ srand関数→rand関数で発生させる擬似乱数の発生系列を変更します。
* rand関数は、同じ繰返しで擬似乱数を発生させるので、起動し直しても、毎回同じパターンの乱数値に\\ なってしまい、利用者に覚えられてしまいます。
* そこで、起動時に、srand関数で発生系列を変更するようにしました。その時の系列値は、タイマー割り込み\\ で常にインクリメントしている変数を用います。系列を変更するタイミングは、利用者がプッシュスイッチを押\\ した時としましたので、どの系列になるかは不定です。こうすることによって、起動し直しても系列が異なる\\ ので利用者に覚えられることがありません。
* プッシュスイッチを押して、直ぐに結果が出るのでは面白くありませんので、徐々に速度を落としながら結果\\ が出るようにしました。
* また、LEDの点灯だけでは、寂しいので、PWMによるブザー音も発生させました。
//**********************************************************************
#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)の順になります。
右上の大きい丸状のものは、圧電スピーカです。
右下のプッシュスイッチは、スタート用のものです。
{{:imgpaste:202004:htmikan-20200428-183034.png?500}}
起動時には、全LEDが点滅しますので、この間にプッシュスイッチを押してください。
そうすることにより擬似乱数の発生系列が変更されます。
{{:imgpaste:202004:htmikan-20200428-183101.png?500}}
サイコロの目が1~6の時の、LEDの点灯パターンです。
{{:imgpaste:202004:htmikan-20200428-183135.png}}{{:imgpaste:202004:htmikan-20200428-183140.png}}
{{:imgpaste:202004:htmikan-20200428-183147.png}}{{:imgpaste:202004:htmikan-20200428-183152.png}}
{{:imgpaste:202004:htmikan-20200428-183158.png}}{{:imgpaste:202004:htmikan-20200428-183203.png}}
如何ですか?
これを2セット用意するとゲームの幅が広がるかもしれませんね。^_^
このページは稲崎様の閉鎖したHPのコピーで、著作権は稲崎様にあります。[[elechobby:picdic:picdic|詳細]]
This page is a copy of Mr. Inasaki's closed website, and the copyright is held by him.[[elechobby:picdic:picdic|Details]]