ロザンヌ開発の経緯(3)

前回に続いて書いていきます。今後も開発の節目節目の出来事について書いていく予定です。亀の歩みですし稚拙な文章ですが興味のある方はお付き合いいただければと思います。

duefuku-rosanne.hateblo.jp

前回↑では開発着手にあたりマイコン(PIC)の選定とプログラムの書き込み装置(PICkit3)など必要な機材の購入まででした。機材は一応それなりに揃ったので、次はPC上でのプラグラム開発環境です。

PC以外に必要なものが2つありまして、

が必要となります。IDEはMicrochip社のMPLAB IDEで決定。CコンパイラはHi-TECH CやCCSCなどいくつか選択肢があるようですが、当時そんなことすら理解してませんでした。

理解してない状態でMicrochipのサイトからIDEのバージョン8.92をダウンロードしてインストールするも、プログラム言語を選択する画面でC言語がなくアセンブラしか選択できない状態。当時よく分かってなかったのですがCコンパイラは別途インストールする必要があるらしい。ですがやり方がよく分からず少し古いバージョン8.84を導入したところCコンパイラのHi-TECH Cが同梱されていたので、とりあえずそれで進めることに。これでようやくC言語でプラグラムを書いてコンパイルできるようになりました。

で、プログラムを始める際の定番としてLEDを一定時間置きに点滅させるプログラム(いわゆるLチカ)をネットから拾ってきてコピペし、初めてコンパイルしてみましたがエラーとなりコンパイル失敗。原因をネットで調べて分かったのが、同じ内容を記述するにしてもコンパイラによって表現が違うとのこと。PICには基本的な設定としてConfigurationBitという設定があり、この表記がコンパイラによって異なるらしく、ネットから拾ってきたのは導入したHi-TECH CではなくCCSC用のものでした。そこでネットで調べてConfigurationBitの記述をHi-TECH Cの表現に修正。それが以下のものです。

#include <htc.h>
int at 0x2007 __config =
_HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF & _MCLR_OFF & _LVP_OFF & _BODEN_OFF;

void main(){
  unsigned int i;
  ANSEL = 0x00;  //アナログ不使用
  PORTA = 0x00;  //RAはlow
  PORTB = 0x00;  //RBはlow
  TRISA = 0x00;  //RAは出力
  TRISB = 0x00;  //RBは出力

  while(1){
    PORTA = 0x00;  //LED消灯
    for(i=0; i<30000; i++){}

    PORTA = 0xff;  //LED点灯
    for(i=0; i<30000; i++){}
  }
}


2行目の__config = 〜がConfigurationBitの設定で、ここを修正したら無事コンパイル成功!この時点では#include <htc.h>とかConfigurationBitの設定の意味すら分かってませんが、とにかくプログラムを書いてコンパイル出来たので非常にうれしかったです。最終的に機能を詰め込みまくったロザンヌですが、はじめの一歩はたったこれだけのプログラムでした。

今回の件で分かったのが、

  • PICは確かに老舗のマイコンなので作例などの情報がネット上に豊富にある
  • ただし開発環境の違いや古さが原因で使えない情報もある

ということです。2つ目については当たり前ではありますが身をもって体感しました。

今回はここまでということで。最後まで読んでいただきありがとうございました!

ロザンヌ開発の経緯(2)

新年明けましておめでとうございます。
今年もマイペースで更新していきますのでよろしくお願いいたします。

マイコンの選定

duefuku-rosanne.hateblo.jp
以前の記事でNRS-1をベースにして自分の欲しい機能を追加した連射を開発すると決めたものの、いきなり出来る訳もありません。マイコンを使う必要があるのは間違いないのですが、

  • マイコンは何を使うか(PIC、AVR、Arduino、RaspberryPiなど)
  • それらのマイコンの中でもどの品番を使うか
  • プログラム言語はC言語アセンブラ
  • 回路図やプリント基板の設計用CADはどんなものがあるのか
  • プリント基板の試作はどうするのか

などなど決まっていないことだらけです。まあ何を決めないといけないのか、多少なりとも理解している程度には知識があったのが救いです。


まず肝心のマイコン選定ですが、何となくMicrochip社のPIC(ピック)がいいかなと思っていました。PICに関する知識はほぼなかったですが、選定理由としては

  • 昔からよくホビー用途にも使われているっぽい(某店の連射装置にも使われていた模様)
  • 昔から使われているならネット上に豊富な情報がある(だろう)
  • ネットで調べると扱いの難しいアセンブラだけでなくC言語が使えるっぽい

という点で仮決めしました。古いマイコンなので2015年の時点でもPICなんて今更みたいな風潮もあったようですが、情報の多さ(推測)で決めました。ちなみにPIC=Peripheral Interface Controller(周辺機器の入出力インターフェースコントローラ)らしいです。

◆PICの選定

次に1000種類あるPICの中から具体的な品番を決めていきます。コンパネ入力と基板への出力ピン数や設定用のスイッチの数を考えると

  • コンパネ入力:ABCDEFスタート上下左右×(1P/2P)で22ピン
  • 基板への出力:ABCDEFスタート上下左右×(1P/2P)で22ピン
  • 設定用スイッチ:ABCDEFスタート上下左右で11ピン+α
  • 設定切替用Dipスイッチ:4~6ピン程度

で少なくとも60以上の入出力ピンが必要となります。これだけピンの多いマイコンをいきなり使うのはハードルが高いので、まずは練習用にピン数が少なくブレッドボードに挿して使えるDipタイプ(昔のゲーム基板によく載っている基板裏面に部品の足が出ているタイプ)で選ぶことにしました。
ネットでPICの作例を調べてみるとPIC16F84というのがかなり多いように見えましたが、2015年時点でリリースから15年以上経過しているらしく、後継品を調べたところPIC16F88と分かりました。これならDipタイプの18ピンで、作例の豊富なPIC16F84のコンパチなので練習用に良さそうということでPIC16F88に決めました。


ということで、PIC16F88と、PCからPICへプログラムを書き込むためのライター(PICkit3)と、実験用のブレッドボード類をマルツオンラインで購入。こんな感じです。(図はMicrochipのサイトより引用)

f:id:duefuku:20211228104323j:plain
PICkit3とブレッドボード上に載せたPIC

これが2015年7月末のことです。ここから数年間どっぷりと開発にハマって行くことになります。


今回は以上です。最後まで読んでいただきありがとうございました!

ロザンヌの名前の由来

前回からかなり時間が経ってしまいました。連射のバグが発覚したため、ブログの更新はバグの修正が終わってからにしようと思ったのですが思ったより手間取ってしまいました。ようやくバグ修正の目処がついたので、またぼちぼち書いていこうと思います。だらだら書いていきますがお付き合いいただければ。


今回はロザンヌの名前の由来について書いていきますが、大学時代にさかのぼります。
大学時代にゲーセン(というかほぼグラIIばっかり)にハマっていた私は、初めてのバイト代でグラIIの基板とシグマのコントロールボックスを購入しました。購入当初は滅茶苦茶うれしくてゲーム漬けの毎日で、基板にハマって以来色んな基板(ほぼシューティング)を購入していきましたがそのうち不満を覚えるようになりました。私のやるゲームは最大3ボタンで、あるゲームはCボタンをAの連射ボタンにしたり、別のゲームではCボタンをA+Bの同時押しにしたりしたかったのですが当時の環境ではそれが出来なかったためです。


出来ないなら作ってしまおうということで、シグマのジョイスティック部分だけ自作することにしました。作ったジョイスティックは以下の仕様です。(うろ覚えなので多少違うかも)

  • ABCDEFの6ボタン(上段:ABC、下段:DEF)
  • 機能はA=D、B=E、C=F
  • ロータリースイッチでC=Fボタンの機能をC/A/AB同時押しの3つから選択可能
  • ABCDEFボタンそれぞれに対しトグルスイッチ×6で連なし/シンクロ30連を割り当て可能
  • ケースはアルミケース


写真が残ってないのが残念ですがこのジョイスティックの出来にはかなり満足していて、たまに遊びに来る友人にも好評でした。ある日友人の一人が「これだけ出来がいいなら何か名前つけようや。ロザンヌとか?(笑)」と冗談で発言したのが強烈なインパクトで、正式(笑)な名前としました。およそこういった装置の名前と思えない絶望的なダサさと、そこはかとなく甘美な響きがむしろ気に入りました。当時ホワイトハウス箱崎でバイトしていた友人のWGFC-はいご氏に伝えたところ「ロwザwンwヌwwwww」な反応だったのを覚えています(笑)


それから25年以上経ってマイコンを使った多機能連射装置を新たに作った訳ですが、連射装置の名前はどうしようか、となったときに自然と「ロザンヌ」が浮かび上がりました。他にも考えてはみましたが、自分としてはこの名前以外にないと思ったので正式な名前としました。この名前は未だに自分で口に出して言うのが恥ずかしいですがようやく少し慣れてきました(笑)
なお品番のR-03Nは完全に後付けで、ロザンヌと読める文字列を当てただけです。心の中ではアールゼロサンエヌと読んでいますが読み方はお任せします。


と言うことで名前の由来でした。最後まで読んでいただきありがとうございました!
来年もマイペースで更新しますのでよろしくお願いいたします。

ロザンヌ開発の経緯(1)

今回から何回かに分けてロザンヌ開発の経緯について書いていこうと思います。

◆2015年、高槻リブロス

2015年当時、私は大阪府高槻市にあったゲーセン「リブロス」でとあるゲームのハイスコアに挑戦(スコアタ)していました。そのゲームには自作の連射装置を付けさせてもらっていて、標準のボタン以外に以下のボタンを備えていました。分かる人には何のゲームか速攻でバレそうですが(笑)

  • Aの裏30連(OFF-ON)
  • Bの表15連(ON-OFF-OFF-OFF)
  • AB同時押し

この連射装置は少数の汎用ロジックICを使用した割と簡単なもので、当時その環境でハイスコアを出してはいたものの、実はもう少し欲張った連射装置の構想がありました。それは以下のような特殊な連射です。

  • Bの表15連で、ボタンを離すタイミングに関係なく15連射を必ず6回、12回、18回…のように6の倍数回だけ出力する(自分の中では6n15連と呼んでいました)

文章だけでは伝わらないと思うので図示するとこんな感じです。

f:id:duefuku:20210320155149j:plain
6n15連のタイムチャート。ボタンを離すタイミングに関係なく6n回出力する。


この連射の構想はそれこそ15年以上前からあったのですが、どんな回路を組んでいいか分からず放置してました。ですがネットで調べつつ学生時代に勉強したことを思い出しながら何とか作ることが出来ました。学生時代(一応電子工学科)にもっとちゃんと勉強しておけば良かった(笑)
作ったのはいわゆる順序回路(フリップフロップ)を使った回路で、前述の連射や同時押しをすべて含んだ連射装置です。下の写真が現物です。

f:id:duefuku:20210320103124j:plain
リブロスで使用していた連射装置。Aの裏30連、Bの表15連、AB同時押し、Bの表6n15連の4出力

このように汎用ロジックICを8個も使用しています。この装置が思い通りに動いた時はそりゃもう滅茶苦茶うれしくて、スコアが出たのと同じかそれ以上の感動でした。そんなわけで早速リブロスに新しい装置を持参して付けさせていただき、再度スコアタに勤しむことになりました。

◆ホームレス

ところが2015年4月に思わぬ事態が発生しました。ホームゲーセンだったリブロスの閉店です。正直かなりショックで、結局新しい連射装置を使ってハイスコアを出すことはかないませんでした。
リブロスが閉店したためスコアタを今後どうするかというのもありましたが、当時の自分としてはそれよりも新しい連射装置がうまく動いた時の喜びの方が上回っている感じでした。自分でアイデアを考えて設計したものが思い通りに動く感動みたいなもんでしょうか。この時点でスコアタよりも連射を作る方に意識が向いていたのを覚えています。手段が目的化するというやつです(笑)その一方でこんなにややこしい回路を都度設計して作ってというのは面倒だな~とも思っていました。

◆偉大なる先駆者

ちょうどその頃、NRS-1という画期的な連射装置が市販されていました。(2021年3月現在も販売中です)
ntls.shop-pro.jp
このNRS-1はマイコンを使用することでユーザーが自由にボタン割り当てや連射速度を変更でき、複数の設定が保存できるという大変素晴らしい製品です。当時自分でもこんなのが作れたらなーと漠然と思っていましたが、私はマイコンを触ったこともなく自分に出来ると思っていませんでした。ですがリブロス閉店で時間が出来たことや、新しい連射装置がうまく動いたことで多少自信がついたのか、自分でもマイコンを使った連射装置を作ってみたいと思うようになりました。マイコンに関する知識はほぼなかったですが、完成形のイメージとしてはNRS-1という先駆者がありましたのでそれにならって作ってみたいと思う気持ちが日に日に強くなっていき、一念発起して挑戦することにしました。目標はNRS-1をベースに自分が欲しい機能を追加した連射装置です。


とまあこんな感じでロザンヌの開発に着手することになりまして、2015年7月ごろの話です。今思えばNRS-1とリブロス閉店がなかったらロザンヌも存在していなかったかもしれません。そう言う意味でもNRS-1とその開発者様には大変感謝しています。


今回はここまでとします。最後まで読んでいただきありがとうございました!

メインループと割り込み処理

前回の記事では基板への出力処理について書きました。今回は出力処理とそれ以外の処理との分担について書いていきます。

◆メインループ

ロザンヌのすべての処理はプログラミング言語C言語)で記述されており、出力処理の他にもユーザーによる設定や液晶画面への表示など様々な処理をしていて、大まかな流れは以下の通りです。

f:id:duefuku:20210305233208p:plain
メインループ

基板の電源を切らない限り水色の部分を無限に繰り返します。これをメインループと呼びます。

◆割り込み処理

で、前回書いた出力処理はこのメインループ内に含まれておらず、独立した処理としてプログラムに記述されています。こんな感じです。

f:id:duefuku:20210305233101p:plain
メインループと出力処理

この図のようにメインループと出力処理を往復することになりますが、メインループ ⇒ 出力処理の流れはいわゆる「割り込み」として処理されます。割り込みについて仕事をしている状況で例えると、

  • メインループ:自分の仕事
  • 出力処理  :電話応対

みたいなものです。仕事中に電話がかかってきたら自分の仕事をいったん止めて電話に出て、電話応対を終わらせたらまた自分の仕事に戻る、という感じです。これで割り込みのイメージは何となく分かると思います。

仕事中に電話がいつかかってくるか分からないのと同じで、メインループから見ると割り込みがいつ発生するか分かりません。というのは半分間違いで、割り込みの発生条件はプログラムする自分で決定します。ロザンヌでは以下3つの割り込み条件を設定しています。

  1. 垂直同期信号(VSync)の立ち下がり発生時
  2. 0.1msタイマーのカウントアップ時(0.1ms経過した時点)
  3. 2msタイマーのカウントアップ時(2ms経過した時点)

なのでちょっとくどいですが、ver.3の処理を文章で書くと

  1. メインループ中にVSyncが立ち下がったらメインループからいったん出力処理に行ってそっちの処理(0.1msタイマー開始)を済ませてメインループに復帰する。
  2. メインループ中に0.1msタイマーがカウントアップ(0.1ms経過)したらメインループからいったん出力処理に行ってそっちの処理(0.1msタイマーのカウントアップ回数加算)を済ませてメインループに復帰する。(ただしカウントアップ回数がユーザー設定値に到達した時のみ2msタイマー開始&コンパネ状態チェック~出力計算を実行してからメインループに復帰する。)
  3. メインループ中に2msタイマーがカウントアップ(2ms経過)したらメインループからいったん出力処理に行ってそっちの処理(基板へ信号を出力)を済ませてメインループに復帰する。

となります。

◆実際の処理の流れ

以上を前回の記事の絵と合わせて表現すると以下のような感じです。(見づらくてすみません)

f:id:duefuku:20210320150613j:plain
メインループと出力処理(割り込み)の流れ

普段はメインループで処理していて、割り込みが発生するたびにそっちの処理を済ませてすぐにメインループに復帰する、というのを繰り返します。出力処理を割り込み処理にしたのは前回の冒頭で書いた通り最重要処理と思ったからです。出力処理を最優先にすることで連射の安定化を図っています。


この辺の作りは常識的な範囲なのか逸脱しているのか自分でもよく分かりませんが、安定した連射出力を得るという目的は達成できているっぽいので概ね正しいのでは、と思っています。


それでは今回はここまでということで。次は何を書こう...

ロザンヌの信号出力処理

アーケードゲーム基板専用多機能連射装置:R-03N(ロザンヌ)の中の人、duefukuと申します。これからロザンヌのことを不定期でちょこちょこ書いていこうと思いますのでどうぞよろしくお願いします。
ゲーム基板に関してある程度知識がないと意味不明かもしれませんが何となく伝わったらいいなーと。


で、初っ端からいきなりですが最重要である基板への信号出力処理について説明します。ユーザーのコンパネ操作をロザンヌで把握して基板へ信号を出力する処理ですが、大まかな流れは以下のようになっています。(※図中のms=ミリ秒:1/1000秒です)

◆ ロザンヌver.2までの処理

  1. 基板の垂直同期信号(VSync)の立ち下がりをきっかけに一定時間のカウント開始
  2. 一定時間経過したらコンパネ状態(レバーやボタンの入力状態)をチェック
  3. 設定内容とコンパネ状態から基板への出力を計算
  4. 計算終わり次第計算結果に基づき基板へ信号を出力

f:id:duefuku:20210228121924p:plain

一定時間待つ理由は、色んな基板に対して相性問題の起こりにくいタイミングで出力するためです。またVSync立ち下がり時点ではなく一定時間後にコンパネ状態をチェックする理由は、ギリギリまで待ってなるべく出力処理と近づけた方が良いと考えたからです。

◆ 出力タイミングの調整

ロザンヌver.3からは基板へ信号を出力するタイミングを調整できるようになりましたが、これは以下の通りです。

  1. 基板の垂直同期信号(VSync)の立ち下がりをきっかけに0.1msタイマーのカウント開始
  2. 0.1msタイマーのカウントを繰り返し、出力タイミングに到達したら3へ移行
  3. コンパネ状態をチェック
  4. 設定内容とコンパネから基板への出力を計算
  5. 計算終わり次第計算結果に基づき基板へ信号を出力

f:id:duefuku:20210228122012p:plain

この図のように0.1msタイマーの繰り返し回数をユーザー側で設定可能とすることで、0.1ms刻みで出力タイミングを調整できるようになりました。
一方、ここでもver.2までと同様に出力の計算が終わり次第基板へ信号を出力しています。設定内容によっては出力の計算にかかる時間が変動するため、このやり方では基板へ信号を出力するタイミングが安定せず1ms程度前後します。ここにまだ改善の余地があります。

◆ ロザンヌver.3以降の処理(最終版)

そこで最終的にver.3以降では出力タイミングを安定させるために以下のようにしています。

  1. 基板の垂直同期信号(VSync)の立ち下がりをきっかけに0.1msタイマーのカウント開始
  2. 0.1msタイマーのカウントを繰り返し、出力タイミングに到達したら3へ移行
  3. 2msタイマーのカウント開始
  4. コンパネ状態をチェック
  5. 設定内容とコンパネ状態から基板への出力を計算
  6. 2ms経過したら計算結果に基づき基板へ信号を出力

f:id:duefuku:20210228122034p:plain

出力の計算にかかる時間は設定内容で変動するものの、最長でも2ms以内には収まります。そこで計算開始から2ms経過したら基板へ出力するよう2msタイマーを使うことで、出力タイミングを安定させることが出来ました。このため上の図で出力タイミングの設定値を0にしても実際に出力されるのは2ms後となります。出力タイミングの最速が2msなのはこう言う事情です。本当は2msをもっと縮めたかったのですが、色んな機能を詰め込んだ影響もあり私にはこれが限界でした。


ロザンヌの信号出力処理は大体こんな感じです。この様な処理をするには汎用ロジックICでは難しいためマイコンを使用してソフトウェア(C言語)で実現していますが、それなりに安定して連射できているようです。


今回はここまでにします。最後まで読んでいただきありがとうございました!次の記事はいつになることやら...