アクセスカウンタ

プロフィール

ブログ名
KazHatブログ
ブログ紹介
Palmwareを気の向くまま作っています。
このブログでは、最近購入したSheevaPlug+について書いていこうと思います。Linuxも初めての初心者に使えるかどうかわかりませんが、先人の知恵を借りながらチャレンジしていきます。
PICはじめました。最近は、ロビのことしか書いていませんね。
zoom RSS

PICでSDHCカードを制御してみる実験(1)

2017/01/10 21:52

久々にPICで遊びました。

思うところがあって、SDカードを使えるようにしたいと思っています。

 

しばらく開発環境もさわっていなかったので、確認してみると、MPLABXは、v3.50にアップデートされ、XC8もv1.40になっていました。これらをまずインストール。

 

今回の実験のためのハードとして特殊なものは、SDカードですけど、ソケットが必要です。これは、昔購入しておいたSDカードソケットを使おうと思います。

これは、元々、最初にPICを使い始めた時に参考にした「PICを使ったデータ・ロガーの製作」に付属の基板に取り付けるつもりで購入したのです。当時の記事はここ

しかし、結局使わずにしまっていたものでした。

 

このソケットを使うにしても、そのままでは、実験するのに使い勝手が悪いので、ブレッドボードに挿せられるようにユニバーサル基板上に載せてみました。

それが、以下の写真です。

DSCN0327msohtmlclipclip_image001

 

ユニバーサル基板は、秋月電子の十字配線ユニバーサル基板 Cタイプをカットして使っています。

十字配線の一部をカットすることで配線なしに接続が可能なので、配線が不要で便利でしたが、ご覧のように、見た目は汚くなってしまいました。

SDカードとのインタフェース用に9ピン分のヘッダを取り付けていますが、実際には、写真の左から8ピン分しかつなげていません。SDカードの右端のPin8に相当するピンは、中途半端な位置にあるためと、PICと接続する場合、SPIモードで使うことから、不要なピンとなるので、接続することをやめたためです。

 

また、ソケット側には、カード挿入検出ピンもありますが、これも接続するのに面倒な状態なので、接続をあきらめました。

 

PICでの実験では、SDカードのPin1〜7だけあれば事足りるということなので、問題はないでしょう。後で必要なら、Pin8も接続できるようにヘッダピンは用意しているのは、その時の保険と考えてください。

 

さて、次には、回路を組む必要があります。

まずは、ターゲットのPICを決める必要があります。少ない手持ちのPICから選択するわけですけど、SDカードの読み書きには、512バイトのバッファが必要というような情報から、RAMは最低それ以上ないと困りそうです。そうすると、あまり小さいPICではだめそうです。

 

PIC18F14K50が使えそうですけど、MPLABX上でMCCを使うと楽ができることを学んでいるので、MCCを使いたいところですけど、最新のMCCでも18F14K50は、対象のPICには入っていませんでした。残念。そのため、対象から外します。

 

手持ちにPIC16F1705というものがありました。これは内部にオペアンプが入っているという変わり種で、面白そうなので、入手しておいたものでした。これはMCCのサポート対象となっているので、これを使ってみようと思います。今回はオペアンプは関係ありませんけどね。

 

普通なら、回路を先に作るのがよいのかもしれませんが、PICはピンの選択に色々とソフト上の制約があったりしますから、先にMCCで設定をしてしまおうと思います。

それに合わせて回路を構築しようという、普通とは逆の順序で進めようかと思います。

 

MPLABXを起動して、新規のプロジェクトを作成します。ここは従来と変わるところがありませんから、説明は省略します。

そして、MCCボタンを押して、System ModuleのEasy Setupの設定をします。

INTOSCで、16MHz_HFにして完了させます。

 

次に、SPIインタフェースのため、Device ResourcesからMSSPを選択してダブルクリックして追加します。

ModeをSPI Masterに変更します。通信速度をいくらにすべきかよくわかりませんが、とりあえずデフォルトのままFOSC/4、すなわち4MHzにしておきました。5MHz設定にしたという情報をネットで見かけましたので、問題ないと信じたいと思います。

 

SPIの動作モードは、モード0で良いらしいのですが、モード3に設定していても動作するとのこと。

この辺、混乱しています。モード0とは、CLKがLowでアイドル状態で、立ち上がりエッジでデータを取り込む仕様ということらしいですが、MCCでは、そういう設定にすると、表示上は、SPI Mode=1となってしまいます。モード0と表示して欲しいところですが、私が間違っているのかもしれません。

だめだったら、後で治すことにして、下記のように設定しました。

無題0

 

SDカードのCSピンは、SPIとは別に制御必要そうなので、1ピン追加します。

Pin Manager (最初表示されていなくて戸惑いましたが、ウインドウの一番下のステータスバーの所にあり、クリックしたらウインドウが表示されました)を使って、どのピンが適切かわかりませんが、今回は、RC3をGPIO Outputに定義しました。実際には空いているカギの絵をロックされたカギの絵に変更します。

無題1

 

そして、どのようにデバッグしたらよいか?できるだけ最小のハードで実験したいので、まずは、書き込み実験だけを行うことを考えました。

SWを1つ取り付け、SWを押したら、ファイルに適当な情報を書き込むと言った感じ。

その後、SDカードのデータをPCで読み出してみようという計画です。

 

そのため、SW用にRC4をGPIO Inputに定義しました。設定はデフォルトのまま、WPU (Weak Pull-up)の設定がされています。これをプッシュスイッチを介してGNDにつなげば、ボタンを押したときにLowが伝わります。

状態は、以下のように変更されました。

無題2

 

なお、RA0 (ICSPDAT)とRA1 (ICSPCLK)は、PICKit2と接続して、プログラムを書き込むために使用しますので、空けています。

ここで、SPIのデフォルト設定では、SDOが設定されていないことに気づきました。SDOの所で、RC2を割り当てました。

Pin Managerの上の方にあるMSSPの所で、以下のように変更しました。

無題3

 

動作確認用のLEDも追加しておいた方がよいと思いつき、RA5に割り当てました。設定はデフォルトのまま、WUPで、LEDの-側をRA5に接続し、2KΩの抵抗を介して、VDDに接続します。RA5を0にしたらLEDが光るという設定ですね。

 

以下が今回の最終形となります。

無題4

無題5

名称もプログラムで分かりやすいように変更しています。

 

以上で設定が完了したので、Generateボタンを押して、ソースプログラムを生成します。

 

接続が決まりましたので、上記の設定に従って、ブレッドボードを組みます。

DSCN0328

大体こんな感じです。回路図は書いていませんが、単純なので、お許しください。

 

プログラムの作成に入ります。

 

プログラムは、ボタンを押したら、カウントアップしていき、かつ、ファイルヘッダ名+カウンタというファイル名でファイルを生成して、中身にカウント値を書き込むという感じにしてみます。

 

初めて使うPICなので、まずは、LEDを点灯させることから始めてから、上述の動作を実現させる本格的プログラミングに移行したいと思います。

 

名称を変更しているので、LED_PORT=0;とだけプログラムして、コンパイルします。

問題なくコンパイルできました。

 

で、ここで、大問題が判明しました。PICkit2では、16F1705をサポートされていないことに。

 

せっかく購入したのに使えないものを買ってしまった。別のPICに変更しなくてはいけないかなどと考え始めました。でも、ちょっと思い返して、ネットで調べてみようと思いつきました。さすが、頼りになるのが、ネットの力。からくり工房「ききょうや」さんが、そのものずばりのPIC16F1705をPICkit2で使うという記事をアップしていました。

定義ファイルを頂き、PICkit2で16F1705を認識させることができました。ありがとうございました。

ありがたく使わせていただきたいと思います。

これで、心置きなく16F1705を使うことができます。めでたしめでたし。

 

おかげさまで、ちゃんとプログラムを書き込め、LEDを点灯させるという第一歩はクリアできました。

でも、点灯だけだと、ちょっと心配だったので、点滅するようにちょっとプログラムを書き換えてみたりして、ちゃんと使えることは確認しました。

 

さて、SDカードの読み書きですが、これをゼロから作るのは大変そうだし、そんな労力をかける必要はないと思い、先人たちのソースを活用させて頂くことにしたいと思います。

それでも、どうなっているか理解して使わせてもらおうかと思っていますけど。

 

ここからは、少しボリュームが必要かと思うので、ここで、いったん切りたいと思います。

続きは後日。連休中に終わらなかったので、次まで少し時間が空くかもしれません。

記事へブログ気持玉 / トラックバック / コメント


ISO Recorder 3.1でDVD-Rへ書き込み

2016/12/23 11:23

ISOファイルを生成した後、DVDに書き込むソフトとしてISO Recorderなるものを使ってみました。

 

インストール後、対象のファイル上で、マウスの右クリックを押すと、プログラムから開くの中に、ISO Recorderというそのままの名前が出てきますので、それを選択します。

すると、ISO Recorderが起動して、以下のウインドウが出てきます。

image

書き込む対象のファイルは、Sourceの欄のImage fileの所にあります。

記録装置側の設定は、Recorderの欄内にあり、私の環境では、FドライブがDVDドライブになっています。

また、16倍速対応のDVD-Rを使っているので、16xが選択されている状態になっています。

 

ここで、Nextボタンを押すと、書き込みがすぐ始まります。

 

完了すると、以下の画面が表示され、Finishを押すと、終了となります。

image

 

あまりいじるところもなく、非常にシンプルですが、必要十分な機能が無料で提供されていること感謝したいと思います。

 

今日はこれだけ。

記事へブログ気持玉 / トラックバック / コメント


DVDStylerを使ってDVDファイルを作成

2016/12/20 21:55

映像ファイルをDVD化するソフトとして、DVDStylerというのを見つけました。

結構使いやすかったので、紹介します。

これは、バージョン 2.6.1をベースにしています。確認してみたら、今は最新版として3.0.2となっていました。まだ試していませんが、この記事も参考になると願っています。

 

作成手順:

 

最初に起動した時、以下の画面が出ます。

映像形式、横縦比、音声形式の初期値を設定します。

image

設定を保存しておけば、下半分にある既存のプロジェクトから選択もできます。

 

新規を選んだ場合の手順

 

1.背景画像選択

以下のメニュー用のテンプレートを選択します。

image

これは、お好みで、選択します。

 

そうすると、以下のような感じになります。

image

右側の大きな画面が、選択したメニューのテンプレートになっています。

その中に、白い四角が3行ほど見えると思います。最初これが何かわからなかったのですが、日本語が文字化けしているものとわかりました。

ダブルクリックして、フォントを選択し直すときちんと表示されます。

 

まずは、タイトル部をダブルクリックすると、以下のウインドウが表示されます。

image

 

テキストを必要に応じて変更して、その右にあるフォント設定ボタンを押します。

そうすると、以下のウインドウが開きます。

image

タイトルなので、文字は大きめに48のサイズに設定をしました。

つまり、タイトルをダブルクリックして変更したのは、テキストの文字と、フォント設定だけということになります。

 

次に、タイトルの下の2行の文字化けを同様に変更します。

ただ、2行は、ボタンとなっており、ちょっとタイトルとは変更できる内容が異なります。

imageimage

フォントの設定だけを行いました。

 

設定が完了した後の画面は、以下のような感じになりました。

image

ウインドウの下に2つのメニュー、メニュー1とメニュー2という画面が表示されています。これは、DVD再生時に表示されるメインメニューと、メインメニューで、タイトル選択を押した時に表示されるサブメニューです。

「その横に動画ファイルをファイルブラウザーからここにドラッグします」と書かれている通り作業をします。

 

DVDに格納したい映像ファイルを、左のタブのファイルブラウザ、もしくは、エクスプローラなどから下のメニューの隣へ、ファイルをドラッグします。

ここのポイント! この時、Ctrlを押しながらやると、1つのタイトルとして読み込まれます。

よくわかっていませんが、複数のタイトルとしてDVD作るより、チャプターを複数にした方が、連続したビデオの作成には、再生時に便利ではないかと個人的には思ったので、こうしました。

 

4つのファイルを読み込むと、以下のような感じになります。

image

上記の絵のように、Ctrlを押して読み込むと、タイトル1からタイトル1-4のように表示され、全体が黒く囲まれて1つのタイトルになっているような表示になりました。Ctrlを押さずに読み込むと、各ファイルは独立したタイトル番号となり、1つ1つの間は白いままで独立しているという感じに見えます。

この例では、1つ30分、2話の映像を4つ分取り込んでいます。約2時間分ですね。

 

このまま、DVD書き込み(F9もしくは、メニューバーの赤い丸いディスクマークを押してもOK)もできます。

しかし、それだと頭出しが面倒なので、チャプター設定をしてみます。

 

そのためには、下に表示されている読み込んだ映像ファイルをダブルクリックして、プロパティ設定画面を出します。

image

ここで、チャプター位置という箇所(中央やや下)の右端の...ボタンを押します。

そうすると、以下のようなウインドウがでます。

image

+でチャプターの追加、−で削除、スパナのマークで設定変更ができます。

上記では、4つのチャプターが表示されていますが、7分おきという設定で自動的に設定されたものです。(初期値では10分置きらしい)

必要なチャプターを選択して、ダブルクリックか、スパナマークを押すと以下のウインドウが出ます。

image

ここで、スライダーを左右に動かすか、時間の右の上下ボタンで、チャプターの開始位置を設定します。 まだ、バグがあるのか、2組ある上下ボタンの右側の細かい時間設定ができる方のボタンは、進む側は動作するものの、戻る側が機能しませんでした。

 

30分番組で、2話入っているソースだったので、オープニング、1話開始、2話開始、エンディングの4か所にチャプターを設定しました。

同様に、ほかのデータにもチャプターを設定します。

 

次にメニュー2をダブルクリックします。

image

そうすると、メイン画面に4つの白枠が表示されていることがわかります。

まず左上の四角をダブルクリックします。

image

アクションのジャンプ先で、このボタン=四角を押した時、どの部分から再生するかを指定します。

また、外観という下半分の所で、映像の...のボタンを押すと、このボタンに表示させる画面を指定できます。

image

 

これで、準備は、完了したはずです。

 

メニュー部の赤いドーナッツ、もしくは、ファイル→DVD 書き込み、またはF9を押してDVDファイルを作ります。

以下のようなウインドウが出ました。

image

今回は、DVDに直接書き込まず、ISOイメージファイルを作ることにしました。

 

開始ボタンを押すと、生成が始まりました。下記ような感じで進んでいきます。

image

終了するまでにそれなりの時間はかかりました。PCの能力に依存すると思いますけどね。

 

出来上がったISOファイルをVLCメディアプレーヤーで開いて内容を確認したら、完了です。

必要なら、ここで、DVDに焼けばOK。

 

ということで、ビデオキャプチャした映像をインデックス付きで、DVD化できるようになりました。

 

今回は、ここまで。

記事へブログ気持玉 / トラックバック / コメント


ビデオのDVD化 HandBrake使用記

2016/12/19 22:44

DVD作成用にisoファイル化してしまったものから映像ファイルを取り出し、一部の映像を入れ替える作業が必要になりました。オリジナルのファイルを削除してしまったので。

 

探してみると、.isoファイルからデータの取り出しには、HandBrakeというソフトがあることがわかりました。これは、評判が良さそうだったので、使ってみました。

 

でも、このソフト、起動後の画面がちょっととっつきにくい感じでした。

しかし、この辺のページをみて、やってみたら、簡単に使えましたので、以下に書いておきます。

 

まず、使った感想を。

 

面倒な点:

ISOファイル内の映像データに複数のチャプタがあった時(今回はそれに当たります)、それをそれぞれ別ファイルとしようと思うと、Destinationのファイル名を1回ごと変更しなければなりませんでした。これが、結構手間がかかりました。連番で作成してくれれば、もっと簡単なのだけれども。

 

よかった点:

下半分のVideoタブでQualityの処で、Avg Bitrateを選択して、2-Pass Encodingにチェックを入れたら、キャプチャした時より、絵がきれいになりました。これは思わぬ朗報でした。

ビデオの映像のキャプチャは720x480ドットで行いましたが、結構ノイズもあり、ブロックノイズのような感じの映像に見えていましたが、2-Pass Encodingにより結構きれいにエンコードできました。

 

以下のキャプチャは、ISOファイルを読み込んで、設定したところです。

image

このISOファイルには、16チャプタあり、MP4で出力しました。上記キャプチャした画面は、最後の16番目のチャプタを取り出す設定を示しています。

面倒な点の所で書いた通り、いちいちファイル名を設定しなければなりませんが、最初は、Startボタンで始め、2回目以降は、その右のAdd To Queueをおせば、どんどんキューにためていけますので、1つのエンコードが終わるまで待つような必要はなく、特に待ち時間といったストレスがなかったことは助かりました。

 

でもDVDの圧縮はそんなにされていないことがわかりました。元のISOファイルサイズが、4.4GBもあったのに、MP4で出力した16個のファイルの合計サイズは、たったの808MBしかありませんでした。約5分の1の小ささです。

 

DVDにしなければ、MP4で保存しておく方が経済的ということがわかりました。

 

今回は、DVDのISOファイルから、映像ファイルを取り出すところまで。では、また。

記事へブログ気持玉 / トラックバック / コメント


VMware上のXPで、VHSファイルのキャプチャ

2016/12/18 17:01

古いもの整理中ですが、VHSテープも、取っておく必要あるのという感じですけど、一部とっておきたいものがあったので、キャプチャしておこうと思い立ちました。

 

何年か前にXSPEED-F1というビデオキャプチャ装置について、書いたことがありました。

その時は、Windows7を使っていた訳ですが、Windows XPでないとXSPEEDが使えないため、苦労した話を書きました。

 

今、Windows10を使っているので、当時と同様に、XP環境を整えないといけない訳ですが、先日来、古い時代のWindowsソフトを動作させるために、VMwareを使うことで、Windows 98を動作させることができることがわかりましたし、そこにたどり着く前に、XPも動かせるようにしていたことも書きました。

 

そこで、WindowsXP SP3のインストールができた環境を使って、PCへのキャプチャ環境を整えてみようと思いました。

 

その話をする前に、少し別の環境でのWindows XP環境も作りましたので、その経緯を。

VMwareを使わない場合、実際にWindows XPをインストールするしかないのですけど、現在の環境も保持しておく必要があります。もちろん、現在の環境がメインだからです。

 

現在のPCの構成は、以下のようになっています。

2TBのHDDにWindowsの環境ができています。こちらは、AHCIでの動作に問題ありません。また、IDEモードでも動作させることはできます。

もう1台、500GBのHDDに、Windows XPの環境を構築しました。

ただし、こちらは、残念ながら、IDEモードだけでの動作となっています。XPでもAHCI動作させることはできるようですが、トライしていません。

 

この2つをBIOS設定で切り替えて運用します。

PCを起動直後、DELキーを押して、BIOS設定画面を表示させ、HDDのどちらを優先させるかを指定して、起動させます。そうすると、選択したHDDにインストールされているWindowsが起動するという訳です。

(追記: 私が使っているマザーボードのメーカーであるASRockのBIOSでは、起動時にBootオプションというのがあり、F11を押すと、どのHDDから起動するかを選択できることがわかりました。その選択は一時的なので、次に起動する時は、元々設定しているHDDから起動するので、切り替えは簡単になりました。)

 

キャプチャしたい時は、XPを起動して、XSPEED-F1付属のUlead Video Studio SE DVDを使い、キャプチャします。キャプチャして、前後の不要部分をカットする作業を行って、ファイルを今のWindows環境に引き渡すことにしました。

 

DVDは、約2時間ほどの動画を格納できますから、複数のVHSのデータを一緒にすることもできます。そういう作業は、時間もかかるので、メインのWindows上でやれば、他のこともやりながらできますので、都合がよいのです。

 

DVDへの書き込みソフトは、どうしようかと考えていましたが、Source ForgeからDVDStylerという素晴らしいソフトが出ていることがわかりました。

 

これは、DVDメニューの設定などもでき、初心者でも比較的に使いこなせる感じなので、お勧めです。

 

これで、XP上でキャプチャして、OSを切り替えて普通の使い方を行うという環境はできました。

しかし、キャプチャは、実時間かかるので、2時間のVHSなら2時間、XPが動く状態を維持しなければならず、普段の作業が滞るということで非常にストレスがたまる環境でした。

 

そこで、VMware上で動作している、WindowsXP SP3上で、USBが認識できるのかとかも含め、動作確認を行ったところできたというわけです。これは、今の環境はそのままなので、作業も並行に行うことができるので、非常に効率的で、別ウインドウで動作しているキャプチャが何時間でも、まったく気にならない環境となりました。

 

以下は、その環境と実際に使うときのメモとなります。

  1. VMwareからXP SP3を起動します。
  2. XSPEEDに付属していたUlead VideoStudioは、XPでないといけないので、VMware上のXPにインストール。これは、普通にインストールできます。
  3. XP上でないと動作しないXSPEED-F1を用意します。まだ、USB接続しません。
  4. Ulead VideoStudioを起動。
  5. Uleadの使い方:
    初期画面で、VideoStudio Editor側を選択し、メインウインドウを出す。
    キャプチャは、タブのCaptureをを選択。右中央部にCapture Videoというのがあるので、クリックすると、準備がほぼ完了。
    ここで、XSPEEDをUSBに接続します。エミュレートされているXPでそのUSBが認識されるので、キャプチャできるようになりました。ここが一番心配していたところでしたが、ちゃんと動きました。
    2回目以降の起動で、すでに接続されていた場合、コネクタを抜き差ししないと、認識されないので注意。
    きちんと認識されると、下記ポップアップがXP上で出て来ました。
    image
    はいを選択して、先に進めます。
  6. 使用方法:
    Source: easycap video adapter
    Format: DVD
    という感じの設定にすれば、OKかと思われます。Formatは、DVDでよいかと思う。お好みで。
    この時、どんな設定でキャプチャされるかは、画面下部のInformationの所に出ています。
    DVDだと、720x480, DVD, Variable Bit R…、MPEG Audio ? Layer 2, 48000といった設定になりました。
    設定を変更したければ、Source/Formatと同じ枠内のOptionsを押して、Video and Audio Capture Property Settingsを選択すれば、ポップアップウインドウが出て、変更ができます。
    なお、このポップアップで、SourceのタブのAudioの所で、Preview audio with USB deviceの所のチェックボックスにチェックを入れておくと、PC側で音が聞こえます。
  7. これで、VHSビデオを再生して、キャプチャを始めたいと思う適当な時間に、Source/Formatと同じ枠内、下側にある、Capture Videoを押すと、録画(PCでのキャプチャ)が始まります。
  8. 終わるときは、同じところを押せば終了です。

という感じの手順でキャプチャはできました。

 

キャプチャしたファイルは、そのままメインのPCでMPEGファイルとして保存しても構いませんが、編集も可能です。私の場合は、TV録画のものだったりするので、CMをカットするなどしました。

 

編集は、キャプチャが終わってから、上部のメニューバーにあるEditタブを押します。

先ほどキャプチャしたファイルが、右側にサムネイル付きであるはずです。それをクリックすると、左側の映像表示ウインドウに表示されます。

 

編集は、次のようにカット作業を繰り返せばOKです。

[と]のボタンが映像ウインドウの真下に見えると思います。

これを使って、取り出したい部分を決めます。小さいウインドウで、少し作業がやりにくいかもしれません。その時は、はさみのボタンの右のボタンを押して、ウインドウを拡大すると作業がやりやすくなるかもしれません。

 

細かい位置決めをしたい時は、[、]のボタンの下に見える時間の所で、時分秒かその下の2桁の所をクリックします。そうすると、数字が点滅するので、その時間表示の右端にある上下三角の所をクリックして、時間を進めたり、戻したりして決めることができます。この時、上下のカーソルキーでも作業が可能でした。

適切な位置になったら、最初[か、最後]を示すボタンを押せばOKです。

範囲が決まったら、メニューのClip→Save Trimmed Videoを押して、指定された範囲の映像を別ファイルとして保存します。

 

この作業を必要なだけ行っていくと、出来上がったファイルは、右側のサムネイルの所にあるので、適切な順番で、画面下部のタイムラインの所に並べていきます。

 

並べ終わったら、上部メニューバーにあるShareタブを押します。(これはわかりにくい名称ですね)

そうすると、画面右中央部にコマンドメニューが表示されるので、その中から適当なものをクリックします。今回は、Create Video Fileを押して、出てくるプルダウンメニューから、Same as Project Settingsを選びました。そうすると、ファイル名を聞いてくるので、適当な名前を付けて保存します。

 

これで、編集されたファイルができあがるということになります。

あとは、そのファイルをメイン側のPCがアクセスできるところに持っていけば完了です。

 

ということで、今はたぶん、誰にも役に立たない覚え書きでした。

記事へブログ気持玉 / トラックバック / コメント


今頃FDDの整理中

2016/10/18 12:53

先日、古いPC関係のものを整理しているという話をしました。まだ、続けています。

 

3.5インチFD(フロッピーディスク)がたくさん出てきたのですが、そのまま捨てるのは忍びなく、できる限りデータを吸い出してしまいたいと思っています。重要な情報は、当時引き継いだはずですが、それほどでもないものは、そのままにしていたのではないかと、はっきりしない記憶状態なので、確認したいという気持ちなのです。

 

ところが、FDの中のデータを取り出すためのFDD (フロッピーディスクドライブ)が、私のまわりからなくなってしまったことに気づきました。

常にどこかのPCでFDDを使えるようにしておいて、必要なら取り出せるようにしておこうと思っていたはずだったのに。。。

メインの自作マシン用のFDDは残っているのですが、前回マザーボードを買い換えた時、FDDインタフェースがなくなっていたので、接続できない状態のまま、今に至っています。そのFDDが接続できるマザーボードは、あまり意識せずに、売却してしまっています。

たぶん、自作PCで使えなくても、実家のPCやら、会社のPCとかを使えば何とかなると思ったような記憶です。しかし、年月が経過して、今現在、FDDを持つPCがまったくなくなっていることに気づいたという次第です。

 

自宅に唯一PC-9821Cx、通称CanBeがあることはあるのですが、この頃のPCには、USBなんてありませんから、読み出せたとしても、今のDOS/VベースのWindowsへデータを持ってくる方法がなくなっているのです。 もし、CanBeを使って何とかしようとしたとしても、相当苦労しそうです。

それは、このCanBeは、HDDで運用していたのですが、そのHDDが故障していたことを何年か前に確認しているので、まず、IDEインタフェースのHDDがなければ、システムの再構築ができい状況だからです。別の案として、FDDベースで使わなければならないとすると、非常に面倒そうです。1台しかFDDはついていませんから、コピーもままならず、ネットも当時モデムを外付けで付けてダイヤルアップで使っていましたから何かを取り込むのも難しそうです。

USBメモリ代わりにインタフェースとして使えそうなのは、RS-232Cくらいしかありませんが、当時CanBeでRS-232Cを使って他のPCと通信をさせるようなことはしたことがないので、そういった環境を構築するのも難しそうです。

 

という訳で、長々書いてしまいましたが、今のPCにFDDをつなぐのが一番よさそうです。ネットで調べると、USB接続のFDDが使えそうです。中古なら1000円程度で買えることがわかりました。

 

FDは100枚くらいありましたから、1枚当たり10円程度の読み出し費用なら、まあ許容できるかと思いました。たぶん今やらないと、将来できないかもしれませんし、最後のチャンスと思って、USB-FDDを調達することにしました。

Logitec LFD-31UEというものです。

 

ネットの情報では、NECの標準フォーマットだった1.2MBタイプ、IBMフォーマットの1.44MB、1MBレベルになる前の720KBタイプの読み出しができる3モードFDDということです。フォーマットは、普通1.2MBはサポートされていないらしいですが、これはできるという情報でした。

 

USB接続して、FDを入れたら、Windows10上のエクスプローラでAドライブとして、普通に読み込むことはできました。

 

まあ、これからフロッピーを使うこともありませんが、フォーマットも試してみました。

NECフォーマットである、1.2MBが可能かどうか確かめてみたかったらです。次のコマンドを打ってみます。もちろんコマンドプロンプト上で。

format a: /f:1232

普通に進みましたが、最後に、ボリュームラベルを入力して下さいというメッセージが出て、特にラベルが不要だったので、そのままEnterを押して進ませました。しかし、最終的にフォーマットに失敗しましたというメッセージが出ました。

 

image

 

こうなると、このフロッピーに対して、もう何も操作できなくなりました。

もう一度フォーマットしようとしても、現在のディレクトリは無効です。というメッセージが出て終わってしまいます。もうこのFDは使えそうもありません。(元々捨てるつもりでしたけど)

なぜかな?

 

悩んでも仕方ありませんし、新たなフォーマットでFDを使う予定もないので、先に進めます。

 

次は、エクスプローラ上で、1.44MBにフォーマットしてみました。これは、問題なく完了しました。

そのFDに対して、今度は、コマンドプロンプト上から、format a: /f:1.23 として、1.2Mフォーマットを試してみます。だめでした。

 

ちなみに2種類のフォーマットの情報を書いておきます。

NECフォーマット:1.23MB、1024バイト/セクタ

DOSフォーマット:1.44MB、512バイト/セクタ

 

あと、このUSB-FDDの挙動不審な点というか使いにくいところがありましたので、書いておきます。

 

1枚目のFDをエクスプローラ上で開いて、コピーなりの作業後、2枚目のFDに入れ替えを行い、同様の作業を行おうとしています。

この時、Windowsがバッファしていた前のFD情報が表示され、新たなFDに入れ替えたことを認識していないような振る舞いをしていることがありました。

 

フロッピーディスクを入れ替えた時の挙動不審状況は以下のような感じです。

 

C:\Users\ohno>chkdsk a:
ファイル システムの種類は RAW です。
RAW ドライブに CHKDSK は使用できません。


C:\Users\ohno>chkdsk a:
ファイル システムの種類は FAT です。
ファイルとフォルダーを検査しています...
ファイルとフォルダーの検査を完了しました。

Windows でファイル システムのスキャンが終了しました。
問題は見つかりませんでした。
これ以上の操作は必要ありません。

    1,250,304 バイト : 全ディスク領域
        1,024 バイト : 1 個の隠しファイル
      560,128 バイト : 32 個のファイル
      689,152 バイト : 使用可能ディスク領域

        1,024 バイト : アロケーション ユニット サイズ
        1,221 個     : 全アロケーション ユニット
          673 個     : 利用可能アロケーション ユニット

 

上記2回のコマンド間には何もFDに対して操作していません。なぜか、2回目には、新たなFDを認識するような感じです。

 

こんな感じでFDの入れ替え時に問題がある場合がありましたが、手持ちの1.2MB、1.44MBのFDのデータをWindows上からコピーして吸い上げることができました。

一部FDでは読み出しができないものもありましたけど、劣化してしまったものと考え、あきらめました。

 

約1000円のUSB-FDDは中々役立ちました。たぶん、これでお役御免でしょうけど、しばらく保存しておこうとは思っています。FDのデータは吸い上げましたけど、システム系、ゲーム系のオリジナルのFDはもう少し保管しておこうかと思っているからです。

 

今回は、ここまで。

記事へブログ気持玉 / トラックバック / コメント


Windows95の頃のアドベンチャーソフトを動かす

2016/09/22 11:32

ジャーニーマンプロジェクト2・Buried in TimeをVMware上のWindows XPにインストールできた話を書きました。その後日談を少し。

 

プレイし始め、特に問題なく動かせたと思ったのですが、問題がありました。

それは、ゲーム中に表示されるアニメーション動画が適切に表示されないというものです。

 

最初のうちは、表示されていたのですが、だんだん表示されないようになってしまいました。せっかくの動画表示ですし、表示がまともでないと、プレイもままならない場面もあります。そのため、そのままにしておくこともできません。これの対策を考える必要が出てきました。

 

この症状が現れて、その昔、XPに変わったときに表示がおかしくなったソフトがあったことを思い出しました。

これは恐らく、OSの表示機構が変わったためのような気がしてきました。

ゲームのマニュアルを読むと、Windows3.1では、Video for Windows1.1が必要だけど、Windows95では直接再生機能を使っているような記述がありました。これがXPではさらに変わってしまったのでしょう。

 

さて、どうしたらよいのか、解決策がなかなか見つかりませんでした。動作条件であるWin95が必要なのかもしれません。

そうこうしているうちに、Windows98のインストールディスクが出てきました。PC-98からDOS/Vマシンに変わって初めてのDSP版Windowsです。前の記事では、32ビットのWindowsのインストールディスクで所持しているのがXPだけだと記載しましたが、Win98があったのでした。XPへ移行した時何も不便がなかったので、Win98が再度必要になることもなかったので、ディスクも含めすっかり忘却の彼方に行ってしまっていたのでした。

 

そのWin98ですが、WinXPよりWin95に近いので、もしかしたら、うまく動くかもしれないと思って、VMware上でインストールしてみました。インストール作業自体は、スムーズに進みました。Windows Updateのような仕組みも不明なので、オリジナルのまま動作させようと思っています。しかし、古いOSであるためか、VMwareのデフォルト状態では、音はならない、マウスの動きにクセがあるといった具合でした。

音がならないのは、今回のゲームプレイに支障を来たします。

調べてみると、Creative社のサウンドドライバがあれば音が出るらしいと分かりました。

Creative ENSONIQ AudioPCI on Windows 95/98というスタンドアローンなドライバなら、VMwareで使えるという情報を得ました。ES1371というカード用のものみたいです。

epw9xup.exeというファイルをダウンロードして、Win 98上でインストールしてみました。

Creative社には、今も提供していただいていること感謝したいと思います。

 

インストールが終わると、音が鳴るようになりました。これはうれしい。

なお、この対策が可能になったのは、VMWare Player 上の Windows 98 で音を鳴らすという記事のおかげです。

 

一方マウスの方は、これといった対処法が見つかりませんでした。多少ましになったと思った設定は、親のWin10上でのマウス設定で、余計な機能 (自動的に既定のボタン上へ移動とかポインタの速度の設定とか) を外すということだけだったと思います。

 

以上のように、Win98の環境が整ったところで、BIT (Buried in Time)をインストールしました。

動作させてみると、XPの時とは異なり、動画表示もばっちりです。

 

しかし、問題が1つありました。CDROMの仮想化環境です。Win98用の仮想化ソフトを見つける必要がありました。XPで使ったMicrosoft製のものはWin98では使えないので、別のものが必要です。しかし、古いOS用のものを見つけるのも面倒です。 少し悩んでいたら、VMwareでISOファイルをマウントする機能があることがわかりました。それを利用してみました。

仮想マシン設定で、ハードウエアのタブで、追加...を押して設定を開始します。ハードウエアの種類で、CD/DVDドライブを選択し、ドライブ接続の選択でISOイメージを使用するとして、ファイルを指定したらマウントが完了します。

 

今回の場合、BITの3つのISOイメージを別々のドライブに割り当てました。

そして、BITの3枚のCD-ROMがどのドライブレターに当たるかを、c:\Windows\Bitmpc.iniに記述することで、CDの入れ替えなしにゲームのプレイができるようになりました。

 

めでたしめでたしです。

 

さて、BITの方ですが、アドベンチャータイプなので、中々前に進ませることができません。全部自力でやることより、完了させたいというのが希望なのです。

 

古いソフトですが、ネットの力を借りられないか調べてみたところ、見つかりました。

日本語版の情報はありませんでしたが、本家がまだ生きていたようです。

Buried in Time

http://thejourneymanproject.com/presto/journeyman2/bithints.html

というページがあり、そこに、ゲームのヒントが英語の記載でしたがありました。

昔やったのは、全体の7割方といった感じで、ようやく、最後まで見ることができました。

 

ヒントが若干わかりにくい表現だったりしていましたし、アクションが必要な画面も出てきたので、ヒントを見たからと言って単純に終わらせられませんでしたから、十分楽しめました。

 

なお、Win XP/Vista/7対応のBITの新バージョン (内容は同じかもしれません)は、オンラインで購入できるようです。価格は、$5.99と昔の購入価格 (9800円でした)から見ると、非常に安いですね。BITは中々のやりごたえがありましたから、興味のある方はお試しあれ。でも英語版だけなので、ハードル高いでしょうけど。

 

皆さんももし、やりかけのソフトがあったら、仮想化してやり直してみるのもよいかもしれませんよ。

 

私は、あと1つ、RIVENという知る人ぞ知るMYSTの後継のアドベンチャーをこれまた、やりかけのままお蔵入りさせていたものがありましたので、こちらもトライしてみようと思っています。

こちらは、さらにCDの枚数が多く、5枚組という豪華なものなので、CD-ROMの仮想化の恩恵も十分得られると思っています。確かこれは、あまり進められず、途中であきらめてしまったのでした。でも、再挑戦しようと思います。これもWin95用なので、たぶんWin98の環境で動かせると思っています。

 

RIVENも上記のBITと同じく、gog.comでMYSTと共にダウンロード販売されているのが見えました。GAMES→ADVENTUREのカテゴリでトップに表示されてるので、いまだに素晴らしいソフトだということだと思います。私は、その前身のMYSTも持っていて、こちらは最後までやりましたけど、非常によいソフトだったと記憶しています。

 

では、また。

記事へブログ気持玉 / トラックバック / コメント


Windows95の頃のアドベンチャーソフトをXPで動かす

2016/09/18 15:10

古いWindowsゲームソフトを動かす

PC関係の古いがらくたを整理し始めました。

 

そうしたら、Win95の頃に購入したゲームソフトが出てきました。

ジャーニーマンプロジェクト2/Buried in Timeというアドベンチャータイプのソフトです。

このソフトは、途中までやったものの、最後まで終えることができないまま、環境の変化などで、そのままお蔵入りになっていたものですが、終わりまでいかなかったので、ちょっと気になっていたのです。

 

ずいぶん昔のものですが、Windows用なので、今のWin10で動くのかなと思い、試しにインストールしてみましたが、インストールすらできませんでした。

このソフトは、Windows3.1と95が動作環境となっていました。

ちなみに当時Buried in Timeを動かしていたマシンは、PC-98で、たぶんWindows95だったのではないかと思われます。

でもWin10 (64ビット版)にインストールもできないのは、なぜなの?と思い調べてみると、当時のOSは、おそらく16ビット版と思われますが、それに対応したソフトは、今の64ビットのWindowsでは動かせないということらしいです。16ビットから32ビットに移行していく時は、下位のOS用のソフトを動作させるサポートソフトがあったらしいですが、Win10でWin95 の対応ソフトを動かすようなサポートはないということだということらしいとわかりました。

 

でも、何とか動かせないのかと思って、調べているうちに、上述のように32ビットのWindowsなら、16ビットのソフトも動くようにするWindowsのソフトのサポートがあるらしいことがわかりました。ですが、64ビットになってしまった今、その恩恵には預かれないということらしいです。

じゃあ、昔のWindowsを引っ張り出すかしないと思いましたが、私の所有しているOSで32ビットのものは、XPしかありません。その次に購入したWin7は32ビットかと思いきや、64ビットだったのでした。ということでターゲットは必然的にXPとなります。

 

でも、XPを単にインストールして使うのは面倒ですし、既存のWin10とは別に運用しなければなりませんから、管理が面倒そうです。何か良い方法はないかなと思って調べてみると、仮想化の技術を使って、Win10上で、XPを動かせることが最適ではないかということがわかりました。

仮想化のソフトはいくつかあるようですが、私は、メジャーなVMware Workstation Playerを選んでみました。

 

VMware WorkstationにXPをインストール

VMwareの設定を行い、DSP版CD-ROMからWindowsXPをインストールしました。今のマシンは、当時と比べるまでもなく高速なので、それほど時間はかからずに完了しました。

 

しかし、そこから、少し問題が発生しました。XPはすでにMicrosoftのサポートが終了していたということです。XPがMicrosoftにサポートされていた間は、インストール後、Windows Updateによって、どんどんパッチが当たっていったわけですが、そういうことができなくなってしまっていたのです。XPのサポート終了時は、将来XPを使うことも予定していなかったので、アップデート用のサービスパックも保存していません。

私の持っているXPは、SP1です。それを何とかSP3までにはしたいと思ったわけです。でも自動的にそれが実現できないので、別の方法を考えねばなりません。

 

SP+メーカー

ここで、SP+メーカーというソフトがあることを思い出しました。これは、オリジナルのディスクに、アップデートソフトをパッチを当てて、所望のバージョンのインストールディスクを作るものです。

これなら、もしかしたら何とかできるかも、と思って起動しましたが、アップデートプログラムがその格納場所からなくなっていたりして、途中でエラーとなって完了できませんでした。

 

アップデートするソフトの一覧は、SP+メーカーが持っていたので、それを見て、何とかならないかと調べると、アーカイブとして保存しているサイトを利用するのが1つの対処法ということがわかりました。

それは、XPのService Packがダウンロードできなくなった対処方法2016年2月という記事に書かれているように、INTERNET ARCHIVEのサービスで、ダウンロードしたいURLを入力して見つかったら、それをダウンロードするという手法です。

結構面倒な作業でしたが、何とかSP+メーカーのlistフォルダに格納されていたdefault_wxp.lstに記載があった214個のファイルほぼ全部を手動でダウンロードしました。不要と考えたIE6/7関係のプログラムはスキップしました。

手動でダウンロードはしましたが、結局アーカイブサービスからダウンロードする必要があったのは、5件だけでした。

残りが全部、Microsoftのサイトの元の格納個所にあったわけでなく、20件だけは、Microsoftからダウンロードしたものの、Microsoft Updateカタログのページで検索してダウンロードする必要がありました。しかも、このページは、ieでアクセスする必要がありましたので、少し面倒でしたし、ファイル名も変わっているものがあったりして、推定して元のファイル名に変更して、SP+メーカーで認識できるようにしました。

 

必要なソフトを全部ダウンロードしたら、SP+メーカーでは、ダウロードしたフォルダを指定することで、ダウンロードさせないようにして、SP3のディスクを生成できました。これで、WinXP SP3を直接インストールすることができるようになったはずです。

 

そう書いたのは、上記を完了する前に、VMware上にインストールしたXP SP1上で、ダウンロードしたSP3を使って、アップデートできてしまったからです。そうしたら、Windows Updateがまだ機能しているようで、しばらく時間が経過すると、自動アップデートも動いてたぶんSP3のインストールだけでは不足だったアップデートのインストールをするように促す黄色のアイコンが現れたりしました。

 

ということは、SP1ではWindows Updateは動作しませんでしたが、SP3ならまだ、必要なセキュリティパッチが自動で当たるようにMicrosoftのサーバが稼働しているのだろうと思いました。

 

でも、それもいつまで動いているかわかりませんから、上述のSP+メーカーで最新版のSP3のインストールディスクを作っておくのもよいと思いました。結局今回は、これは使っていないので、動作確認して置く必要がありますね。時間があったらやりたいと思います。

 

これで、32ビットOSであるXPの環境が用意できました。

 

Buried in Timeのインストール

いよいよ、Buried in Timeをインストールしてみます。これは、豪華CD3枚組のソフトです。

そのため、ゲーム途中でCDを入れ替えるようにメッセージが出て動かすのですが、それが結構面倒だったことを思い出しました。でもCDチェンジャー(懐かしい名前ですね)対応となっており、ドライブが複数あれば、どのドライブにどのCDが入っているのかをあらかじめ設定しておけば、CDを入れ替えずにゲームが使える仕組みになっています。

今は、物理ドライブは1つしかありませんので、ここは、CDの仮想化を行って、CDを入れ替えなしで、プレイしたいと思いました。

 

まず、CDROMの内容をisoファイルにする必要があります。それは、簡単でした。Win10のエクスプローラで、CDを挿入したドライブをマウス右クリックすると、以下のようなポップアップがでます。

image

その中から、Create image from CD/DVDという項目を選択します。

そうすると、Record CD/DVDというタイトルのソフトが立ち上がるので、isoファイル作成先を指定してNextを押せばコピーされます。

image

これは、Windowsの標準機能だそうです。便利になったものです。

コピーが完了したら、Finishを押して終了させます。

 

CDのデータをISOファイルとして準備できたら、次は肝心のCD-ROM仮想化ソフトを用意しないといけません。探してみたら、Microsoft謹製のVirtual CDRom Control Panelというソフトが良さそうです。これは、XPから7まで使えるソフトなので、VMware上のXPにもインストールできます。

 

ダウンロードしたwinxpvirtualcdcontrolpanel_21.exeを実行すると、3つのファイルが生成されました。

readme.txt、VCdControlTool.exe、VCdRom.sysです。

readmeに手順が書いてあるので、それに従って作業を進めます。

VCdRom.sysは、%systemroot%\system32\driversフォルダに入れます。

そして、VCdControlTool.exeを実行します。

仮想ドライブの追加を行い、先ほど作成したisoファイルをその追加したドライブにマウントします。

 

これで、CD-ROMがなくても、仮想的にアクセスできるようになりました。

 

準備ができたところで、Buried in TimeをXP上でインストールしてみます。Win10の時とは異なり、ちゃんとインストールできました。

そして、実行してみると、ちゃんと動きました。すばらしい。

でも、設定を忘れていました。上述したように3枚のCDROMがどのドライブに入っているか指定しないといけません。c:\Windowsの下に、BITMPC.INIというファイルができているはずなので、DiskPath1=W:\、DiskPath2=X:\、DiskPath3=Y:\のような感じで、3枚のCDがどのドライブにあるかを記述しました。これで、CDを入れ替えずに、ゲームを進行させられます。

 

では、さっそく楽しみたいと思います。涼しくなってきたので、こういうアドベンチャータイプのものを楽しむのによい季節ですから。

 

なお、マウス、サウンド、ディスプレイ等は、VMwareの標準状態で対応できており、特別に何かする必要はありませんでした。

 

ではまた。

記事へブログ気持玉 / トラックバック / コメント


停電からSheeva関連で問題発生した時の経緯

2016/09/16 22:16

東京電力からスマートメータに取り換えると連絡があり、一時的に停電となりました。

その後、色々と問題が発生しました。

外部からSheevaPlug+のWebサーバにアクセスできなくなりました。

停電だけが問題ではなく、この前のOSのバージョンアップも絡んでいたようです。

 

SheevaPlug+上で動作させていたソフトの初期設定が必要みたいです。

サーバはずっと稼働させっぱなし状態みたいなものでしたから、すっかり何をしたか忘れてしまっています。

過去の記事やらを見ながら設定していきます。

 

まずは、サーバが外部からアクセスできるようにしないといけません。

無料ダイナミックDNSを使っていましたが、たぶん、WAN側のIPアドレスが変わってしまったように思えます。

 

私の場合、kazhat.dip.jpという名称で、家サーバさんのところで登録管理してもらっています。

 

そこからddns-update.plをダウンロードしてきて、そのプログラム内に、$ACCOUNT、$DOMAIN、$PASSWORDを設定します。

これを/usr/lcoal/ddnsディレクトリに格納しました。

Debianの新バージョンをインストールした後、これをすっかり忘れていて、何もしていなかったのでした。

ここの設定に関しては、ダイナミックDNSサービスを利用してみるに、書いていました。

 

以下のように実行していきました。

/usr/local/ddns$ sudo crontab -e
[sudo] password for ohno:

エディタが開くので、

5,35 * * * * /usr/local/ddns/ddns-update.pl

を書き込んで、^xを入力すると、/tmp/crontab.0nuDqH/crontabに書き込むみたいです。

 

crontab: installing new crontab

という表示が出て、終了しました。

 

でも、終わってみると、書き込んだはずのファイルは、そこには、ありません。

どうも、/var/spool/cron/の下のcrontabsの下に格納されたみたいです。

 

 

/usr/local/ddns$ sudo ./ddns-update.pl

と入力して、試しに起動したところ、うまく動いたみたいです。

 

current_ipとip_update.logというファイルが生成されました。

 

crontabも実行したので、たぶん、30分ごとに更新されるはずです。

 

この後、外部からアクセスできるようになりました。

 

大した話ではありませんでしたが、今回はこれで終わりです。

記事へブログ気持玉 / トラックバック / コメント


長年のナゾ@キーボードonWin10、ようやく解決

2016/08/16 18:03

私のPCのキーボードは、Unixマシンを使っていたことや、emacsを常用していたことから、キーボードのAの左隣のキーは、ずっとCtrlキーとして使用していました。

そのため、通常左CtrlキーとCaps Lockキーを入れ替えを何らかのソフトや設定で行っていたのでした。

 

しかし、昨年Windows10にアップグレードした時、使っているキーボードの挙動がおかしくなっていました。それは、左CtrlキーもCaps Lockキーも同じキーコード、つまり、同じ機能になってしまったのです。そのため、元のCaps LockキーにCtrlキーの機能を割り当てると、左下のCtrlキーもCtrlキーの動作のままとなり、Caps Lockを行うボタンがなくなってしまっていました。

 

Caps Lockを使うことはないので、それでも良いと思っていましたが、今日、ふと、デバイスマネージャーのキーボードのドライバの詳細をみたら、見慣れないCtrl2Cap.sysというファイルが設定されていることに気づきました。

これは、何だろうと調べてみると、Mark Russinovichという方が作成したCtrl2capというソフトということがわかりました。

そこには、アンインストールのやり方(ctrl2cap.exe /uninstallと実行)も書かれており、実行したら、Ctrl2capのドライバが削除されました。(管理者権限のコマンドプロンプト上で実行し、要再起動)

このドライバ、c:\Windows\System32\driversの下にあったのですが、日付が2012年と古く何か怪しいと感じたのですよね。それから、調べてみたら上記の情報にたどり着いたという次第。

 

まったく記憶がありませんが、何かの時に、これをインストールしてみたのでしょう。でもその存在を忘れ、確かWindows7の頃からレジストリに書き込む手法をとっていて、なぜかWindows10にアップグレードした時、そのドライバがSystem32に残っていたので、自動的に適用されてしまったのではないか推察しています。

 

このCtrl2capをアンインストールすると、当該フォルダのctrl2cap.sysは、簡単に削除できました。

すると、Caps Lockと左Ctrlキーは、それぞれ元の機能に戻りました。

 

そして、いつものようにregeditを起動して、

\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout

の下に、Scancode Mapを作成します。これは、Keyboard Layoutの所で、マウス右クリック→新規→バイナリ値で新しい名前を作成して、名前をScancode Mapに変更します。

そして、それをダブルクリックして、編集画面を出し、次を設定すれば完了です。
00 00 00 00 00 00 00 00
05 00 00 00 1d 00 3a 00
3a 00 1d 00 01 00 29 00
29 00 01 00 00 00 00 00

上記は、データだけなので、ご注意を。

終端コードの0000まで、5組のデータがあることを示しており、1d00が左Ctrl、3a00がCaps、Esc=0100、半角/全角=2900で、それぞれ、コードを入れ替えていることを示しているとのこと。

 

ともかく、古いドライバを間違って使っていたことが分かって、めでたしめでたしということでした。

 

では、また。

記事へブログ気持玉 / トラックバック / コメント


ダイソン掃除機にPICが入っている

2016/08/12 22:52

少し、PICをいじる時間がなくなっている今日この頃です。

 

たまたま、興味深い記事を見かけました。

 

ダイソンの掃除機の分解解析記事です。日経テクノロジーに掲載の「分解スペシャリストが見た!スゴイ製品その中身」という連載で、「

人気も吸引力も衰え知らず、Dysonのサイクロン掃除機」という記事です。

Dyson DC62という機種を分解して、解析したというものです。

なお、リンクの記事は、8/26までだけ一般無料公開ということなので、お早めに。

 

興味を持ったのは、Dysonの掃除機のメイン基板にPIC16F1936のSOPタイプのものが使用されているという所です。普通(?)の家電で、PICが使用されているものがあることを初めて知りました。
マイコン制御という言葉はかなり昔から聞きましたけどね。最近は死語かも。

 

上記は、メイン基板ですが、バッテリ部のサブ基板というものもあり、そちらには、PIC16LF1827が使われているとのこと。

 

16F1936は、使ったことがありませんが、16F1827は、PIC時計に使いました。

16F1936は、28ピン、8KW、25I/O、最大動作周波数32MHzという感じのスペックで、特筆するような機能はなさそうです。

 

実は、我が家では、かなり前のDC12という機種のDyson掃除機を使っています。もしかしたら、これにもPICが入っているのかもしれません。

なんとなく、親近感がわきました。

記事へブログ気持玉 / トラックバック / コメント


SheevaPlug+からWindows10のファイルアクセス

2016/08/11 18:15

Windows10のアニバーサリー版がリリースされたというニュースがありました。

順次自動アップデートされるという話でしたが、私のPCには、1週間経過した8/9になっても、その気配がありません。待ちきれなくなり手動でアップデートしました。

 

Windowsメニューに出方など色々変わっている(改善されている)ところもあるようですが、それはネットの情報にお任せしたいと思います。

 

このアップデートが原因かどうかわかりませんが、SheevaPlug+からWindowsのファイルアクセスができなくなってしまいました。

その回復に少し苦労したので、その経緯を書いておきます。

 

以前記事にしたように、リモートアクセスのプログラムを動かすなど、ファイルの共有で対応しているので、ファイルアクセスができなくなると、所望の動作ができなくなるので困ります。

 

ファイルの共有は、sambaの機能を使って、SheevaPlug+側でPCのフォルダをマウントすることで実現しています。

 

例えば、以下のような感じでマウントします。

sudo mount -t cifs //192.168.1.12/sharedFile /media/sharedFile/ -o iocharset=utf8,file_mode=0777

 

192.168.1.12というのは、LAN内で割り振られているWindowsPCのURLです。

sharedFileというフォルダを、SheevaPlug+の/media/sharedFileというディレクトリに割り付けるわけです。そのほかのオプション、cifsは、Windowsのファイル共有サービスを使ってアクセスできるようにするものみたいです。文字コードをiocharsetで指定しています。utf8にしているのは、SheevaPlug+側がそれでないとうまく漢字を表示できないからです。file_modeは、unixのファイル属性でおなじみのもので、ここでは、読み書きOKの設定にしています。

 

一方、Windows側では、sharedFileというフォルダのプロパティで共有設定を行っておく必要があります。

image

共有タブの共有...を押して、出てきたウインドウで、Everyoneを選び、追加ボタンを押します。

image

アクセス許可レベルは、読み取り/書き込みとして、フルアクセス可能に設定しました。

最後に、右下にある共有ボタンをおして、次のウインドウで、終了ボタンを押して、設定完了です。

 

普通なら、ここで、SheevaPlug+側で先ほど示したように以下のようにマウントすればOKのはずです。

sudo mount -t cifs //192.168.1.12/sharedFile /media/sharedFile/ -o iocharset=utf8,file_mode=0777

しかし、Permission deniedというエラーが出て、マウントできません。

今までできていたはずなのに、結構な時間解決できず、調べる時間もなく放置状態でした。

 

ようやく時間ができて、よく見てみると、上記のsharedFileのプロパティ画面の一番下の下の資格の中、パスワード保護のところを見ると、共有フォルダにアクセスするには、ユーザーアカウントとパスワードが必要と書かれていることに気づきました。

設定を変更した方がよさそうなので、リンクをクリックしてみました。

 

ウインドウが出てきました。大きく3つの設定区分がありました。

ゲストまたはパブリックのところが、以下のように、ファイルとプリンタの共有を無効にするとなっていたので、有効する方を選択しました。

image

さらに、すべてのネットワークの所をクリックして広げると、2か所関係ありそうな箇所がありました。

パブリックフォルダーの共有の所と、パスワード保護共有の所です。

image

これを上記のキャプチャのように設定して、変更の保存ボタンを押したら、このウインドウが消えました。

 

そうして、再度SheevaPlug+側でマウントさせてみると、ようやく、マウントされ、ファイルにアクセスできました。

 

昔は、どうやったのか記憶にないのですが、たぶん、ちゃんと設定したのでしょうけど、やり方をすっかり忘れてしまったということだと思います。

 

これで、また元通りになりました。

 

今回は、これだけ。

記事へブログ気持玉 / トラックバック / コメント


焦電型赤外線センサ (D203B) を使ってみた

2016/07/21 20:36

焦電型赤外線センサ、いわゆる人感センサを使ってみようと思います。

 

すでにたくさん情報あるので、大した情報にはならないかもしれませんけど。

 

秋月電子さんから、焦電型赤外線センサD203Bを購入しました。100円でした。

それと、フレネルレンズ S9001も合わせて購入しました。このレンズは、Senbaの焦電センサがすっぽり入るとしか書かれていませんが、D203BがNanyang Senba社となっているので、これだと判断したわけです。

 

ネットでよく見かける記事では、センサはAKE-1 (RE-210)を使ったものがほとんどでした。

これを使ったら、情報も多く簡単そうです。

でも、レンズのことを考えると、ちょっと心配でした。

 

図面を見る限り、RE-210の外形が8.3mmΦ (カタログには、RE-200Bしか掲載されていなかったので)で、D203Bが8.2mmΦと違いがあります。 一方、フレネルレンズ側で、センサがはまるところの内径が8.2mmです。

 

秋月さんのページのコメントにあるようにD203Bなら、すっぽり入るでしょうけど、RE-210だときつかったりして入りにくかったり、使えないと困ります。

 

心配なので、D203Bを購入することに決めたわけです。

もう一つの心配の使用例がほとんど見つからないという所は、参考回路を参考にすることで対処することにします。

 

回路

回路は、D203B参考技術資料焦電型赤外線センサーとPIC12F675を使った人間検知LED照明制御回路の実験アナログ工作にはまる:焦電型赤外線センサーユニットの制作に記載の回路図を参考にさせていただきました。

 

部品の種類を削減するため、最終的に以下のような回路にして実験です。

PICは、12F1822をとりあえず使うことにしました。

 

image

 

焦電センサからの出力をアンプで増幅して、PICでAD変換して検出しますが、その時の値を確認するため、例のディスプレイとEUSARTと接続してデバッグします。

また、LEDも付けて、人を感知したらLEDを光らせる実験もできるようにしました。

 

回路は、焦電型赤外線センサーとPIC12F675を使った人間検知LED照明制御回路の実験のものとほとんど変わりません。

2段目のアンプのバイアス電圧は、手持ちの抵抗を使ったので、10Kになっていますが、VDD/2を作っているだけなので、同じですね。

 

第1段の非反転増幅で22.3倍、第2段の反転増幅で21.3倍と、合わせて約474倍の増幅をしています。D203Bのアプリケーション例では、1段目は同じですが、2段目が180倍増幅になっていたので、約10倍もの差があります。アプリケーション例では電圧が12Vとなっていたので、3.3V位を考えていた私の回路を考慮すると、まあまあのところでしょうかね。

 

もっと詳しい説明は、赤外線検出ユニット 回路説明をご覧になるのがよいと思います。

私が説明しなかった、コンデンサに関する説明もされています。

 

電源を入れて、2段目のオペアンプの出力電圧を手持ちのマルチメータで測定してみると、通常時1.7V前後、手をかざすと、2V程度になっていました。

電圧は、かなり揺らいでいました。1.7Vというのは1.6V〜1.8V位ですかね。

実際には、人がセンサの感知範囲に入ると、2Vぐらいになった後、1.7Vに戻り、さらに、感知範囲から人がいなくなると、今度は、1.3Vに下がるという反応を示していました。Webのどこかで見たような記憶があるのですが、センサは、赤外線が変化したことを出力しているようです。一種の微分波形のようなものと思えばよいですかね。

 

今回は、人がセンサの範囲外から範囲内に入ったことを検出するだけにしてみました。

つまり、定常電圧から、一定レベル以上の電圧になったら、人が範囲内に入ったと判断するわけです。

 

PICのプログラムとしては、増幅したセンサからの出力AD変換させ、適当なしきい値を超えたら人を感知したと判断させればよいので簡単そうです。

 

プログラムの作成:準備編

では、PICのプログラムを始めましょう。

 

すでに説明していますが、たまに書いておかないと古いものを検索するのも面倒になるので、詳細を書いていきます。

 

いつものように、MPLAB X IDEを立ち上げて、新規プロジェクトを作成します。

imageを押して開始します。

  1. Choose Project:Standalone Projectを選択して、Next >を押します。
  2. Select Device:今回使用するPIC12F1822を探して選択して、Next >を押します。
  3. Select Header:特に何もせず、Next >を押します。
  4. Select Tool:書き込み用ツールを選択します。私の場合PICkit2しか持っていませんが、今回は赤ランプが付いていて選択できません。次に進めるため、緑ランプのものを適当に選択して、Next >を押します。MPLAB Xの統合機能が使えないですが、大きな問題はないと思っています。
  5. Select Plugin Board:ここは、自動的にスキップされました。
  6. Select Compiler:XC8を使うので、その最新版のXC8 (v 1.37)を選んで、Next >を押します。
  7. Select Project Name and Folder:プログラムを格納するフォルダとプロジェクト名を設定します。Encodingは、Shift_JISがよいでしょう。 Set as main projectにチェックが入っていた方がコンパイルする時、面倒がないと思います。以下のような感じです。

image

最後にFinishを押すと完了です。

 

プロジェクトの準備ができたら、まずは、MCCを使って、基本のプログラムを生成してもらいます。

imageを押して開始します。

以下は、すでに設定が済んだ状態のキャプチャですが、説明しやすいと思って、最初に掲載しておきます。

image

最初は、左上のProject Resourcesの中、Systemの下の3項目だけが登録されているはずです。

 

最初に、System Moduleを選択 (初期時に選択されていると思います)します。Easy Setupで、500kHz動作にしてみました。そんなに高速動作はいらないと思ったからです。

そして、PLL EnabledとLow-voltage programming Enableの2つのチェックを外しました。

これで、System Moduleのところは、完了です。

 

次に、Pin Moduleと思いましたが、必要なリソースを追加します。

左中央のDevice Resourcesから今回必要なADCと、EUSARTを追加します。

ADCをクリックして展開し、ADCが現れるので、それをダブルクリックします。そうすると、左上のProject ResourcesのPeripheralsにADCが追加されるはずです。

同様に、EUSARTをクリックして、その下のEUSARTをダブルクリックします。

そうすると、Project ResourcesのPeripheralsにEUSARTも追加されるはずです。

 

また、画面下部にPin Managerの所が、初期状態から変わるはずです。

 

ここで、Project ResourcesのPin Moduleをクリックします。

そして、どのピンを有効にするか設定していきます。それは、下部のPin Managerのウインドウ内で行っていきます。

 

今回、PIC 12F1822の8ピンDIP品を使っているので、Packageの所でPDIP8を選択すると、実際のPin Noと表示が合います。12F1822では、どのPackageを選択しても、Pin Noは同じですね。

 

ADCは、アンプの出力をつないだRA2ピンの所をクリックします。すると、緑の背景で、カギがかかったアイコンに変わり、Pin Managerウインドウの上にあるPin Moduleというウインドウに1行追加されると思います。

そうしたら、いくつか設定しておくとよいかもしれません。設定するのは、Custom Nameの所、ここは、プログラムするときわかりやすい名前にすればよいと思います。今回は、PIRとしました。それと、初期時WPUにチェックがついていたので、ここのチェックを外しました。

 

そして、EUSARTの所は、ディスプレイとつなぐピンの設定として、TXの所で、RA4をクリックします。RXの方は設定しません。

上のPin Moduleウインドウで、RA4の所を設定します。Start HighとOutputにチェックを入れました。

 

最後のピン設定は、LED用にGPIOのoutputの所で、RA5をクリックします。

Pin Moduleの設定では、Custom Nameの所をLEDにしてみました。 Outputにはチェックが入っていると思いますが、WPUの方は、チェックを外します。

 

これで設定は完了です。右上のウインドウには、使用するピンの所が緑色に変わります。

ピン名で設定できるところには、自分で命名したPIRとかLEDという名称が表示されるので、配線する時も間違いにくくなっています。

Pin Moduleの完了した時の状態が以下となります。

image

RA0,RA1は、プログラムを書き込むときにPICkit2と接続するDATとCLKになるので、使用を避けています。デバッグ中は、PICkit2と接続したままにしているので。

 

もう少し設定が残っています。Project ResourcesのADCをクリックします。

ここでADCの設定を行います。基本的に初期状態のままでよいかと思いました。Result Alignmentの所は、rightにしました。これは、10ビットのAD変換した数値を16ビットに詰め込むときに上位ビットのMSBから詰めていくか、LSBから詰めていくか指定するものです。通常は、数値として計算しやすい、LSBが詰めるright (右詰め)が使いやすいと個人的には思っています。

他は、変更していませんが、キャプチャしておきます。

 

image

 

最後に、EUSARTの設定します。ここは、デフォルトのままですね。

非同期、9600ボー、8ビット、パリティなしという状態です。これは、受信側の設定と合わせる必要があります。

image

 

これで、プログラムを生成します。

左上のProject Resourcesの右のGenerateボタンを押します。この時、設定ミスとかで、上記キャプチャでも黄色のびっくりマークのタブが見えますが、そこでエラーがあると生成されません。Notifications:0でなく、1以上の数値の時は、中身をチェックする必要があります。中には、エラーでないものも含まれるので、0以外の数値になっていても生成できる場合もありますが、中身はチェックしておくとよいと思います。

 

ちゃんと生成できると、下部のPin ManagerのウインドウがOutputに切り替わり、Generation completeの文字が表示されていれば、OKです。

 

そうしたら、Project Resourcesのウインドウの上に見えるProjectsのタブを押して、ファイルが見えるようにしましょう。

 

私の場合は、以下のような感じになりました。

image

 

プログラム作成編

これから、main.cを書き換えていきます。その他のプログラムは、必要に応じて参照するとよいと思います。

 

main.cをダブルクリックすると、ファイルが開き、ウインドウ中央部に表示されます。

 

今回は、PIRピンの電圧をAD変換して、ある一定の値になったら、LEDをonさせるという形にしようと思います。

 

void main()内に必要なコードを加えていきます。

初期化は、SYSTEM_Initialize();により、行われるようにすでにプログラムが書かれていると思います。

今回は、割り込みも使わないので、コメントになっている割り込み関係の所には手を付けません。

 

そして、以下のような感じにしました。while (1) { }は、最初から記載があると思います。それを置き換える感じでプログラムを書きます。

 

adc_result_t data;

 

__delay_ms(1000);
EUSART_Write(0x0c); //画面クリア
SetCursor(0, 0);
DisplayChar("PIR");

 

while (1)
{
    // Add your application code

    // PIRからの入力レベルをAD変換
    data = ADC_GetConversion(PIR);
   
    // AD変換した値をEUSARTに出力
    SetCursor(0, 0);
    DisplayValHex(data >> 8);
    DisplayValHex(data & 0xff);
    __delay_ms(500);

 

    if (data > 0x240) LED_PORT = 1;
    else LED_PORT = 0;

}

たったこれだけという感じですが、これだけです。 (ディスプレイ関係の関数は除く)

 

whileの無限ループの前に、4行処理があります。これは、別途作成したデバッグ用のLCDディスプレイにメッセージを表示するもので、画面をクリアして、PIRという文字を試しに表示しているだけdす。 EUSART_Write()という関数は、自動的に定義されるものです。これで通信してくれます。SetCursorとDisplayCharは独自関数ですが、説明は省略します。ここも、中身は、EUSART_Writeを行うのですが、わかりやすく、カーソル位置を設定したり、文字列を表示できるようにしたものです。以前示したと思うので、それを探してください。

 

whileの中がメインのプログラムとなります。

PIRと名付けたピンの電圧をAD変換して、16ビットのデータとしてdataという変数に格納しています。

そのdataをディスプレイに16進数で表示させるための4行があります。

そして、最後のif文以下2行が、そのdata値に応じて、LEDを光らせるかどうかを決めています。

 

これをコンパイルして、エラーがなければ、バイナリが生成できるはずです。このプログラムで、256バイトというサイズでした。

 

ここの0x240というのは、ディスプレイに表示された数値を見て、適当に決めました。

前の方で書いたように、通常時、1.7Vくらい、人を感知すると2Vぐらいになりますので、そのレベルに応じた値を設定したことになると思います。揺らぎがあるので、少し余裕を持たせた方がよいかとは思います。

 

今回、VDD=3.3Vで動作させているので、10ビットのAD変換では、通常時1.7Vだと、1.7V/3.3V*1024=527=0x20fになり、2Vだと、2V/3.3V*1024=620=0x26cというレベルになると考えられます。

少し余裕をもった0x240というのは、ちょうどよい数値ではないでしょうか。

 

手をかざすと、LEDが光り、すぐ消えます。これは、センサが人を感知したという変化があったときだけ電圧が上がるからです。そのまま手をかざしておいて、今度は、手をセンサから外すと、電圧は1.4Vとかいうレベルに下がります。この時を検出するように今回はプログラムしていませんから、何も起こりませんけど、LCDディスプレイには、小さい数値が表示されました。

 

これをベースに、人を感知したら、タイマを起動して、一定時間点灯するというプログラムを作れば、前回作ったタッチセンサ付き5灯LEDスタンドのようにタッチせずとも、人を感知して点灯するものが作れますね。

 

意外と簡単に、焦電型赤外線センサが機能したので、ほっとしています。

これも、プログラムの作成で面倒な設定をMCCがやってくれるおかげです。これで、プログラムサイズを最適化して、小さくしてくれると最高なのですけどね。それは割に合わないので、できるだけメモリ容量の大きなものを購入するという方法で対応することにしたと以前に書きましたね。

 

注意事項が1つ。電源を入れてしばらくは、安定しないのか、12〜13秒ほど経過すると、LEDが付きっぱなしの状態になります。その後、1分ほどは手をかざそうが何をしようが反応しません。

最初、ハードがおかしいのではないかと色々いじってしまったりしまいましたが、放っておくのが一番だという結論です。 ネットでも、電源を入れて10秒後に突然出力が1になり、それから30秒は、そのままだったという情報がありました。通常の動きを検出するまで、40秒かかったということですね。私の場合より短いですが、RE210を使われた話なので、違いはあるのでしょう。

 

ちなみに今回の工作の費用は、センサ100円、フレネルレンズ40円、LM358 20円(5個100円)、抵抗計9個(4種類) 9円相当(100本入り100円x4)、コンデンサが電解3個 30円(1個10円)、セラ3個(0.01uF) 30円 (10個入り100円)、PIC 12F1822が100円、LED1個20円位という感じでしょうか。

合計で、350円位といった所でしょうかね。センサモジュールだと、400〜500円位ですから、珍しくお安くできました。なお、ブレッドボードとか、配線代は入れていません。

 

最後に、今の実物の状態の写真を提示します。

DSCN0322

一番左側のブレッドボードが今回製作したもの、その右側は、前回紹介したデバッグ用ディスプレイです。さらに右側に「ほぼPICkit2」が少し見えています。

ディスプレイのブレッドボードには、赤と黒のコードで電源が供給され、黄色のコードがEUSARTの信号線がつながっています。

本体のブレッドボードの中央が焦電型赤外線センサ、右上は、PICkit2からのICSP接続用のケーブルです。電源もここから供給してもらっています。右下にLEDを載せています。

 

では、また。

記事へナイス ブログ気持玉 1 / トラックバック 0 / コメント 0


グラフィックLCDを使ってみる その4

2016/07/16 11:13

説明を続けます。

 

今回は、キャラクタコード0x20(スペース)から、0x7fまでを作ることを前提にプログラムしています。

それ以外の場合は、プログラム内の$codeの値を適切に設定して下さい。ここは、コメントを作るだけなので、間違っていても大勢に影響はありませんけどね。

 

入力するビットマップデータとして、今回は、以下のようなビットマップファイルを作りました。

フォントは、8x8ドットとなっています。区切りを示すドットが左と、下にあります。

image_thumb1_thumb

 

このフォントは、Palmプログラムで使ったもの (今回少し修正しましたけど)です。

ファイル形式は、モノクロでないと、変換できませんので、ご注意を。

 

プログラム内に記載している通り、

perl bmp2txt.pl ***.bmp [output.txt]

とperlが動くシェル上で実行してください。最後のoutput.txtは、省略可で、省略した場合、指定したビットマップファイル名に.txtがついたファイルが生成されます。

私の場合は、Windows10上で、cygwinを動かして、そこで、perlを実行しています。

 

なお、生成されたファイルは、テキストファイルですが、改行コードがUNIXスタイルなので、メモ帳ではきれいに表示されませんので、ご注意ください。私は、Meadow (emacs)でテキストは見ています。

それをMPLAB X IDE上のプログラムにコピーすれば完成となります。

 

一方、MPLAB Xで作成するメインプログラムは、以下のようなもので動作確認しました。

完全なものではありませんが、簡単なものなので、不足分は、すぐわかると思います。

 

LCDg_init();

LCDg_cls();

 

LCDg_pos(0, 0);
for (ii = 0; ii < 96; ii++) {
    LCDg_print(st);
    st[0]++;
}

 

__delay_ms(2000);
__delay_ms(2000);

 

LCDg_cls();


LCDg_setSize(2); //0:Normal, 2:縦2倍, 4:縦横2倍

LCDg_print("AQM1248A Graphic LCD\n");
__delay_ms(2000);
LCDg_print("3 font size !!\n");
__delay_ms(2000);

 

char message[10] = "\nTest000";
const char hexch[] = "0123456789ABCDEF";

 

LCDg_cls();
ii = 0;
LCDg_setSize(2); //0:Normal, 2:縦2倍, 4:縦横2倍
while (1) {
    message[7] = hexch[ii & 0x0f];
    message[6] = hexch[(ii >> 4) & 0x0f];
    message[5] = hexch[(ii >> 8) & 0x0f];
    LCDg_print(message);
    ii++;

    __delay_ms(500);
}

 

このプログラムでは、初期化後、画面をクリアし、定義したキャラクタコード0x20〜0x7fを表示します。16文字x6行表示できますので、全部の文字の状態が確認できるはずです。

その後、4秒ほどwaitした後、縦2倍のフォントで、AQM1248A Graphic LCD他を表示します。

 

そして、その後、Test000と表示します。0.5秒毎に、番号を+1しながら、表示をします。

この時、番号は、16進数になっています。

これは、スクロール機能を確認する意味で入れています。

この例では、縦2倍フォントなので、3行表示になっていますが、LCDg_setSize();の引数を0か4にすることで、フォントサイズを変更できますので、試してみて下さい。

 

表示状態は、以下のような感じです。なかなかいい感じだと自己満足しています。

DSCN0313_thumb[11]

DSCN0313_thumb[10]

DSCN0314_thumb[8]

最初の写真は、前回示した写真と同様の全体像ですが、8x8ドットで、定義した全96文字が、16文字x6行で表示されています。その拡大したものが2番目の写真となります。

最後の写真は、縦2倍表示を示したもので、16文字x3行で、メッセージが表示されています。

 

全体写真をご覧になってお分かりの通り、ブレッドボードの配線は、ジャンパタイプから変更したので、以前キャラクタLCDだけを接続していた時より、かなりすっきりしていると思います。

 

これでテストはできましたので、以前と同様に、EUSARTで他のPICからデバッグ情報を受信して、表示するということが、このグラフィックLCDでもできるようになります。

こちらは、外形がほぼキャラクタLCDと同じですが、最大16文字x6行と、多くの情報を表示できるので、重宝するのではないか考えています。

 

画面表示文字のバッファ変数を大きく取り、画面から消えた情報もある程度保持するようにして、スクロールボタンをつけたら、もっと多くの行数を表示できたりすると思います。

色々とアイデアが浮かびますが、それは、デバッグで使いながら、必要に応じて対応していくようにしたいと思います。

 

これで、今回のお話は、完結です。では、また。

記事へブログ気持玉 / トラックバック / コメント


グラフィックLCDを使ってみる その3

2016/07/16 11:11

フォントの作成に関して書いておきます。

 

フォントデータをプログラムに埋め込むのは、結構面倒だと思います。

すでに、このLCDを使って、プログラムソースを開示している方のデータから頂くのもよいのですが、自分で作るのが、好みのものを作れたり、その時々の条件にあったものを用意でき良いだろうと思っています。そして、最初の1〜2文字は、キャラクタLCDのデータシートに書いてあるフォントを見ながら、バイナリデータに頭で変換しながら、プログラムソースを作るということをやり、表示確認を行いました。

でも、数文字ならその方法でもよいかもしれませんが、今回予定している96文字も作るという作業はやってられません。

 

そこで、ふと思い出したのです。Palmプログラムで作ったフォントデータがあったのを。

MemoViewerというPalmwareでは、自作のフォントで等幅表示をさせました。

 

その時、ベースとなるフォントデータをビットマップで作っていました。

そのビットマップデータは、Windowsの標準ソフトであるペイントを使って作っていました。

この方法だと、少しフォントの形を変えたいという時も簡単です。

 

ペイントでなくても構いませんが、お絵かきソフトで、形状を見て、修正するのが一番良い方法だったからです。また、そのファイルフォーマットがわかるもので、かつ簡単な構造という要求も加わります。それは、以下で。

 

Palmwareでは、フォントデータをテキストの形で、リソースとして与えてコンパイルしていました。

テキストというのは、例えば、数字の5を以下のような形で記述することです。

----
###-
#---
#---
##--
#-#-
--#-
--#-
##--
----
----

 

こういうテキストデータをモノクロビットマップからperlプログラムを使って、生成したのです。

このpalm用のプログラムをそのままでは、今回の用途としては使えませんが、今回のプログラムソース用のデータも作れるはずと、プログラムを改造を試みました。

 

で、どんなperlプログラムかというと、以下のようなものです。

結構力づくで変換していますが、PICの動作に関係なく、たまに使うだけのもですから、お許しください。

 

bmp2txt.plというファイル名としています。

#
# bmp2txt.pl : モノクロbmpをフォントリソースに変換
# 2016/7/10 Copyright Kazuki Ohno
#
# bmpには、最下行に、文字ごとの切れ目マークを入れる。文字の左下に点があること。
# 左端には、行を示す点が必要。
#
# Usage: perl bmp2txt.pl ***.bmp [output.txt]
# 入力:モノクロbmpファイル
# (1)左端に行を示す点を上側と下側に入れる。
# 上端の点は、データ領域に含まれ、下端の点は、含まれない
# これにより、各行が離れたデータを処理が可能となる。
# (2)各文字の左下に点を区切りとして入れてあること。この点は、領域外。
# (3)行の最後は、3ドットの点を区切りとして入れてあること。
# 例:以下のようなモノクロビットマップとなる
# ■:黒ドット(位置を示すマーカ)、□:白ドット、○データ領域
# ■□○○○○○○○○○○□○○○○□○○○
# □□○○○○○○○○○○□○○○○□○○○
# □□○○○○○○○○○○□○○○○□○○○
# □□○○○○○○○○○○□○○○○□○○○
# □□○○○○○○○○○○□○○○○□○○○
# □□○○○○○○○○○○□○○○○□○○○
# □□○○○○○○○○○○□○○○○□○○○
# ■□■□□□□□□□□□□■□□□□■□□
# X方向は、等間隔の必要なし
#
# 出力:テキストファイルを生成
# bmpファイルと同じディレクトリに***.bmp.txtというファイル名ができる。

 

# ビットマップフォーマット
#  00   2   bfType          "BM"    BMPファイル識別符号
#  02   4   bfsize                  ファイルサイズ
#  06   2   bfReserved1     0       予備
#  08   2   bfReserved2     0       予備
#  0A   4   bfOffbits               ファイル内のイメージデータ開始位置
#  0E   4   biSize          40      ヘッダのサイズ
#  12   4   biWidth                 イメージの幅(ピクセル)
#  16   4   biHeight                イメージの高さ(ピクセル)
#  1A   2   biPlanes                イメージのプレーン数
#  1C   2   biBitCount              ピクセルあたりのビット数、
#                                     1,4,8,16,24,32 の何れか.
#                                     (但し、16,32 は圧縮のみ)
#  1E   4   biCompression           圧縮型式
#                                     0  非圧縮、
#                                     0  以外圧縮されている(説明省略)
#  22   4   biSizeImage             イメージデータのサイズ
#  26   4   biXPixelsPerMeter       対象デバイス水平解像度
#                                     (ピクセル / メートル)
#  2A   4   biYPixelsPerMeter       〃 垂直解像度(〃)
#  2E   4   biClrUsed               使用する色数
#  32   4   biClrImportant          重要な色数.0 の時全色が重要
#  36       bmiColors         Color Table (RGBQUAD の配列)開始.
#                             各エントリーは 4 ビット、
#                               (rgb 強度 + 予備(rgbReserved=0)).
#                             非圧縮の場合、
#                               biClrUsed が 0 の場合のエントリー数は、
#                               biBitCount の値に応じて、
#                                 1   2 エントリ
#                                 4   16
#                                 8   256
#                                 24  0.
#                               biClrUsed が非 0 の場合のエントリー数は、
#                               biClrUsed の値に等しい.
#
# bfOffbitsに格納された位置から bitmap データが記述される.
#
# bitmap データは画像のピクセルごとの Color Table のインデックスまたは
#rgb 値である.
# データは画像のピクセルが、左から右へ向かう順に、1行ずつ保存される.
# それぞれの行は、4バイトの倍数になるようにゼロパディングされる.
# 行は画像の下から上へ向かう順に保存される.

 

# 切り上げ関数
sub ceil{
    ( $_[0] == int($_[0]) ? $_[0] : int($_[0] + 1) );
}

 

# ビットマップの左端のドットのY座標を探して返す
sub searchYdot {
    while ($Hcoord < $biHeight) {
# グローバルの$Hcoordの現在の座標位置から最初のドットが見つかるまでデータを読み出す
        $rpos = $bfOffbits + &ceil($biWidth/32)*4*($biHeight-$Hcoord-1);
        seek(IN, $rpos, 0);
        read(IN, $buffer, 4);
        $Hcoord++;

        $data=unpack( "N", $buffer);    #符号なしcharとしてunpack
#        printf("%x: %x\n", $rpos, $data);

        #左端は、文字の上端と下端のペアで区切り
        if (($data & 0x80000000) == 0) {    #黒ドットは、0
            return ($Hcoord-1);    # 見つかったY座標値を返す
        }
    }
    return -1; # エラー時は、-1
}


# ビットマップの各行の下端のドットのX座標を探す
sub searchXdot {
    my ($y) = @_;
    while ($Wcoord < $biWidth) {
        # $Wcoordの最初のデータを読み出す
        $rpos = $bfOffbits + &ceil($biWidth/32)*4*($biHeight-$y-1)+ int($Wcoord/32)*4;
        seek(IN, $rpos, 0);
        read(IN, $buffer, 4);

        $data=unpack( "N", $buffer);    #符号なしcharとしてunpack
#        printf("0x%x: %x\n", $rpos, $data);

        # 32ドットの中に黒ドットがあるかチェック
        $xsub = $Wcoord & 0x1f;
        $Wcoord = $Wcoord & 0xffffffe0;
        while ($xsub < 32) {
            my $mask = 0x80000000 >> $xsub;
            if (($data & $mask) == 0) {    #黒ドットは、0
                $Wcoord = $Wcoord + $xsub + 1;
                return ($Wcoord-1);
            }
            $xsub++;
        }
        $Wcoord = $Wcoord + 32; # 4バイト単位なので、32ドット分加える
    }
    return -1; # エラー
}


# 128x48ドット グラフィックLCD用のフォントをbmpデータから作成

 

$filename = shift;
$address  = 0;

 

open( IN, "$filename" ) or die "Can't open $filename\n";
$fileOut=shift;
#第2引数がない時は、元のファイル名に.txtをつける。
if ($fileOut eq '') { $fileOut=$filename.".txt"; }
open( OUT, ">$fileOut" );

 

binmode( IN );    # 入力するbmpファイル
binmode( OUT ); # 出力テキストファイル
#ファイルは、UNIX形式の改行であること、そうでないとできたファイルがおかしくなる

 

read( IN, $bfType, 2); # BMという識別子が取得されるはず、チェックしていない
printf( "bfType = %s\n", $bfType );
$address  += 2;

 

read( IN, $buffer, 4); # ファイルサイズ
$bfsize=unpack( "V", $buffer);
printf( "bfsize = %x\n", $bfsize );
$address  += 4;

 

read( IN, $buffer, 4); # 読み飛ばし
$address  += 4;

 

read( IN, $buffer, 4); # データ開始位置を示すオフセット
$bfOffbits=unpack( "V", $buffer);
printf( "bfOffbits = %x\n", $bfOffbits );
$address  += 4;

 

read( IN, $buffer, 4); # ヘッダサイズ
$biSize=unpack( "V", $buffer);
printf( "biSize = %d\n", $biSize );
$address  += 4;

 

read( IN, $buffer, 4); # イメージのXビット幅
$biWidth=unpack( "V", $buffer);
printf( "biWidth = %d\n", $biWidth);
$address  += 4;

 

read( IN, $buffer, 4); # イメージのYビット幅
$biHeight=unpack( "V", $buffer);
printf( "biHeight = %d\n", $biHeight );
$address  += 4;

 

# その他のデータはスキップ

 

$code=0x20;

 

# 全データを読み込むループ
$Hcoord = 0;
while ($Hcoord < $biHeight) {

    # 左端にある行区切り情報を探し、最初の行の範囲を取得
    $startY = &searchYdot(); # 開始Y座標
    if ($startY < 0) {
        last;    # ドットデータが見つからない時は、終了
    }
    printf("\nstartY=%d, ", $startY);

 

    $endY = &searchYdot(); # 終了Y座標
    printf("endY=%d\n", $endY);

 

    # 読み込む1行分のデータ範囲が分かったので、1文字分ずつ読み込む
    $Wcoord = 1; # 左端は、マーカーなので、読み飛ばす必要あるため
    $endX = &searchXdot($endY);

 

    while ($Wcoord < $biWidth) {
        $startX = $endX; #前のendXが、次のstartXとなる
        printf("startX=%d, ", $startX);

        $endX = &searchXdot($endY);
        printf("endX=%d\n", $endX);

# もし、startXとendXが連続している時は、3ドットの区切りかチェック
        if ($startX+1 == $endX) {
            printf(OUT "\n");
            last;
        }

 

# ここまでで得たキャラクタの矩形領域をサーチして、データを作成する
        $xx = 0;
        for ($ii = $startX; $ii < $endX; $ii++) {
            $chdata[$xx] = 0;
            $yy = 0;
            for ($jj = $startY; $jj < $endY; $jj++) {
                $rpos = $bfOffbits + &ceil($biWidth/32)*4*($biHeight-$jj-1)+ int($ii/32)*4;
                seek(IN, $rpos, 0);
                read(IN, $buffer, 4);
                $data=unpack( "N", $buffer);    #符号なしcharとしてunpack
               
                $mask = 0x80000000 >> ($ii & 0x1f);

                if (($data & $mask) ==0) { # 黒ドットなら0
                    $chdata[$xx] = $chdata[$xx] | (1 << $yy);
                }
                $yy++;
            }
            $xx++;
        }
        # できた$chdataを出力
        printf(OUT "{");
        for ($ii = 0; $ii < ($endX-$startX); $ii++) {
            printf(OUT "0x%02x, ", $chdata[$ii]);
        }
        printf(OUT "}, // '%c'\n", $code);
        $code++;

    }
}

close( IN );
close( OUT );

 

printf( "%s 生成完了\n", $fileOut );

# end of file

プログラム内容は、見てもらえばわかるはずですので、説明はしません。

特にプログラム最初の所に説明がありますので、お読み下さい。

 

続きがありますが、また、字数制限のため、ここでいったん切ります。

記事へブログ気持玉 / トラックバック / コメント


グラフィックLCDを使ってみる その2

2016/07/16 10:37

では、ソースプログラムを提示します。

 

以下は、lcd.cとして作ったもので、従来のキャラクタLCDのソースに追加しました。

/*
* AQM1248A-RN 48x128ドット SPI接続グラフィックLCD
* 制御ルーチン
*/

//------ Command Write -----
void LCDgCmd(uint8_t data) {

    CSB_PORT = 0;
    RS_PORT = 0;
    SPI2_Exchange8bit(data);
    CSB_PORT = 1;
}

//------ Command Data -----
void LCDgData(uint8_t data) {

    CSB_PORT = 0;
    RS_PORT = 1;
    SPI2_Exchange8bit(data);
    CSB_PORT = 1;
}

/*
* AQM1248A グラフィック液晶の初期化
*/
void LCDg_init() {

    LCDgCmd(0xae); // Display = OFF
    LCDgCmd(0xa0); // ADC = normal
    LCDgCmd(0xc8); // Common output = revers
    LCDgCmd(0xa3); // bias = 1/7

    // 内部レギュレータを順番にON
    LCDgCmd(0x2c); // power control 1
    __delay_ms(2);
    LCDgCmd(0x2e); // power control 2
    __delay_ms(2);
    LCDgCmd(0x2f); // power control 3

    // コントラスト設定
    LCDgCmd(0x23); // Vo voltage resistor ratio set
    LCDgCmd(0x81); // Electronic volume mode set
    LCDgCmd(0x1c); // Electronic volume value set

    // 表示設定
    LCDgCmd(0xa4); // display all point = normal
    LCDgCmd(0x40); // display start line = 0
    LCDgCmd(0xa6); // display normal/revers = normal
    LCDgCmd(0xaf); // display = ON

    // 8x8ドット表示のデフォルト
    LCDg_setSize(0);
}

/*
* 1文字表示
*/
void LCDg_chr(uint8_t data) {
    int ii;

    for (ii = 0; ii < 8; ii++) {
        LCDgData(font[data - 0x20][ii]);
    }
}

void LCDg_str(char *str) {
    while (*str) //文字列の終わり(00)まで継続
        LCDg_chr(*str++); //文字出力しポインタ+1
   
}

/*
* 128x48ドット
* ドット単位で、X,Y座標を引数とする
* ただし、Y方向は、8ドット単位に丸められる
*/
void LCDg_pos(uint8_t x, uint8_t y) {
    // X方向は、ドット単位
    LCDgCmd(0x10 | (x >> 4));
    LCDgCmd(x & 0x0f);
   
    // Y方向は、8ドット単位
    LCDgCmd(0xb0 | (y >>3));
   
}

void LCDg_Update() {
    char ii, jj, kk;
    char trans[] = {0x00, 0x03, 0x0c, 0x0f, 0x30, 0x33, 0x3c, 0x3f,
        0xc0, 0xc3, 0xcc, 0xcf, 0xf0, 0xf3, 0xfc, 0xff,};

    switch (YscrMax) {
        case 3:
            for (jj = 0; jj < YscrMax; jj++) {
                LCDg_pos(0, jj * 16);
                for (ii = 0; ii < XscrMax; ii++) {
                    for (kk = 0; kk < 8; kk++) {
                        LCDgData(trans[font[Screen[ii][jj] - 0x20][kk] & 0x0f]);
                        if (XscrMax == 8)
                            LCDgData(trans[font[Screen[ii][jj] - 0x20][kk] & 0x0f]);
                    }
                }
            }
            for (jj = 0; jj < YscrMax; jj++) {
                LCDg_pos(0, jj * 16 + 8);
                for (ii = 0; ii < XscrMax; ii++) {
                    for (kk = 0; kk < 8; kk++) {
                        LCDgData(trans[font[Screen[ii][jj] - 0x20][kk] >> 4]);
                        if (XscrMax == 8)
                            LCDgData(trans[font[Screen[ii][jj] - 0x20][kk] >> 4]);
                    }
                }
            }
            break;
        default:
            for (jj = 0; jj < YscrMax; jj++) {
                LCDg_pos(0, jj * 8);
                for (ii = 0; ii < XscrMax; ii++) {
                    LCDg_chr(Screen[ii][jj]);
                }
            }
            break;
    }
}


/*
* テキスト表示のクリア
* Screen配列に空白を書き込み、Updateする
*/
void LCDg_cls() {
    int ii, jj;

    for (jj = 0; jj < 6; jj++) {
        for (ii = 0; ii < 16; ii++) {
            Screen[ii][jj] = 0x20;
        }
    }
    LCDg_Update();
    // 画面消去した後は、カーソル位置を0,0にする
    ScreenPosX = 0;
    ScreenPosY = 0;
}

/*
* カーソル位置設定
*/
void LCDg_setCursorPos(char x, char y) {
    ScreenPosX = x;
    ScreenPosY = y;
}

/*
* Scren配列に文字列を書き込み、画面を更新
* 画面いっぱいになったら、スクロールする
* カーソル位置を意識せずに、一種の表示ターミナルとして使用可能
*/
void LCDg_print(char *str) {
    int x, y;
   
    while (*str) {
        if (ScreenPosY >= YscrMax) {
            // スクロールをここに置くことで、最終行が空行に見えることがなくなる
            for (y = 0; y < YscrMax - 1; y++)
                for (x = 0; x < XscrMax; x++)
                    Screen[x][y] = Screen[x][y + 1];
            for (x = 0; x < XscrMax; x++)
                Screen[x][y] = ' ';
            ScreenPosY--;
        }
        switch (*str) {
            case '\n':
                ScreenPosX = 0;
                ScreenPosY++;
                break;
            default:
                Screen[ScreenPosX][ScreenPosY] = *str;
                ScreenPosX++;
                if (ScreenPosX >= XscrMax) {
                    ScreenPosX = 0;
                    ScreenPosY++;
                }
        }
        *str++;
    }
    LCDg_Update();
}

/*
* 文字サイズの設定
*/
void LCDg_setSize(char size) {
    switch (size) {
        case 2: // 縦2倍サイズ
            YscrMax = 3;
            XscrMax = 16;
            break;
        case 4: // 縦横2倍サイズ
            YscrMax = 3;
            XscrMax = 8;
            break;
        default:
            YscrMax = 6;
            XscrMax = 16;
            break;           
    }
}

このプログラムは、素直に作っているので、特に説明は必要ないと思います。

 

それと、ヘッダとして、lcd.hを作りました。

char Screen[16][6]; //16文字x6行分のキャラクタコードを格納
char ScreenPosX, ScreenPosY;
char XscrMax;
char YscrMax;


void LCDgCmd(uint8_t data);
void LCDgData(uint8_t data);
void LCDg_init();

void LCDg_chr(uint8_t data);
void LCDg_str(char *str);
void LCDg_pos(uint8_t x, uint8_t y);
void LCDg_Update();
void LCDg_cls();
void LCDg_setCursorPos(char x, char y);
void LCDg_print(char *str);
void LCDg_setSize(char size);

// グラフィック用 キャラクタデータ
// bmpファイルから、perl bmp2txt.pl [bitmap.bmp] で生成する
const char font[96][8] = {

        {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, // 
〜 省略 〜

};

 

長くなってしまうので、フォント部のデータは省略しています。

フォント部については、次の記事で説明します。

 

グラフィックLCD用の関数は、LCDgで始まるようにしました。

LCDgに続く名前で記述していきます。

最初のCmdとDataは、コマンドとデータをPICからLCDへ送信するものです。

_initは、初期化です。

 

_chrは、1文字だけ表示、_strは、文字列を表示させる関数です。

_posは、表示させる位置をします。X方向は1ドット単位で指定できますが、Y方向は、8ドット単位になっています。Y方向が8ドット単位なのは、プログラムの簡略化のため、手を抜いているからでもあります。

 

_Updateは、画面更新を行います。これは、キャラクタ単位のバッファを持って、縦スクロールを実現させるため、画面全体を再描画するために使います。

 

_clsは、画面全体の消去、_setCursorPosは、キャラクタ単位の座標を指定します。

_prnitは、先の_strとは異なり、画面に表示する文字列を格納するキャラクタ単位のバッファに書き込むものです。その後、_Updateを行うと、実際に描画されます。

 

最後の_setSizeは、文字のサイズ指定です。デフォルトの8x8ドットサイズのほか、縦に2倍と、縦横各2倍のサイズに変更できます。これは、文字を描画する時に、1ドットを縦に2倍したら、縦横2倍にしたりして描画しているので、TrueTypeフォントのような高級なことは行っていませんが、簡単に実装できるので、サポートしました。

 

96文字も定義しているので、768バイトもメモリを消費します。使っているPICは、16F1829なので、8Kワードしかありませんから、結構厳しい量です。256文字全部定義したら、2KBのサイズになります。こういう用途には、PICは向きませんね。

記事へブログ気持玉 / トラックバック / コメント


グラフィックLCDを使ってみる

2016/07/15 22:13

先日は、PICのデバッグのため、8文字x2行のI2C接続LCDを使いました。

 

実は、もう一つLCDを購入してありました。

それは、AQM1248Aという48x128ドットのグラフィックLCDです。

秋月さんのページから頂きました。

表示域が約3cmx1cmと小さいですが、取り回しは良さそうです。

 

今までキャラクタタイプのLCDしか使っていませんでしたので、グラフィックLCDは、気になっていたのです。キャラクタタイプですと、表現に限界があり、PIC時計とか、結構苦労しましたから。

しかし、ここの所、やることが多くて、なかなか試す時間がなかったのですが、ようやく出番となったわけです。

 

このLCDは、ピッチが1.27mmなので、そのままブレッドボードで使うことはできませんが、変換基板があり、それにより、2.54mmという使いやすいピッチに変えてもらうと使えるようになります。

もちろん、それも一緒に購入したわけです。 しかし、完成品ではないので、変換基板にはんだ付けを行わないといけません。

上記の写真の下辺に見える端子が、はんだ付けが必要な1.27mmピッチの部分、左端に見えるのが、変換後の2.54mmピッチの端子です。

 

この1.27mmというのは、私の経験上の最小ピッチです。さて、うまくできるのか。

途中、はんだブリッジとか発生させてしまったりしましたが、何とか、はんだ付けを完了させました。

この工作は、キャラクタ液晶のはんだ付けと同じ時に行ったので、ずいぶん時間が経過してしまいました。ちゃんとはんだ付けができたかは、動作させてみないと、ちゃんと動くかわかりませんから、早く確認しておきたかったのですけどね。

 

さて、確認するためには、PICと接続しないといけません。どのようなハードにしようかと考えましたが、以前作成した8文字x2行LCDのボードに追加するのが良いのではないかと思いました。

 

このグラフィックLCDは、SPI+RSの4ピンと接続させますが、信号線の本数が少ないので、I2C LCDを接続したPIC16F1829にまだ、接続する余裕があったからです。

 

AQM1248Aの変換基板から出ている信号は、計7ピン。VDD/GNDを除くと、5ピンが信号で、/RESETと/CSは、変換基板上でプルアップされていました。残るは、SPIのSCLKとSDIの2ピンとRSを加えた、3ピンで、4ピンは、必要ないのではないかと思いました。つまり、/CSはGND固定させて使えば問題なかろうと思ったわけです。

しかし、これが後々問題となりますけど、この時は、そうは思っていませんでした。

 

AQM1248Aは、SPI接続なので、I2Cとは違う設定が必要です。SPI接続は初めてですがMCCが助けてくれるでしょう。

 

ベースプログラム、設定は、PIC USARTで通信にトライのものをベースとしました。キャラクタLCD

は、接続したままにしています。

 

ハードは、上述のように、AQM0802Aを接続したPIC16F1829は、まだ、ポートが余っているので、グラフィック液晶も追加して、接続します。でも、この時点では、どのピンに接続するか決めていません。どう接続するかは、MCCで、MSSP2を追加してから考えようと思いました。

 

従来のキャラクタLCDを接続した時の設定は、

image

としていました。

 

SPIのため、MSSP2を追加してみると、SCK2はRB7、SDI2はRB5、SDO2はRC1 or RA5となっています。

ところが、RB5のピンが、EUSARTのRXとバッティングしてしまうのです。

そこで、EUSARTのRXピンをRC5に変更しました。これは、EUSART側しか、選択変更できなかったからです。そうすると、以下のような設定となりました。

image

上記では、SPIのほかに必要なRS用にRA5を汎用出力として設定してあります。これは、余っているピンならどこでも構わないのですけれど、何となく決めました。

 

そうすると、SCK2 (10ピン)、SDI2 (12ピン)、SDO2 (15ピン)がSPI用となりますが、SDI2は今回は、使いません。このグラフィックLCDからリードすることができず、ピンもないからです。

そして、新たな接続方法がきまったので、LCDの変換基板とPICを接続しました。もちろん、ブレッドボード上にて。PICのSDO2を、LCDのSDIに接続するところだけが注意するところですかね。

 

電源は、その通りに接続しますが、それに加えて、/CSもLow固定としました。/RESETは、プルアップされていて、動作に問題なければオープンでよいということなので、そのままどこにも接続しませんでした。

 

MSSP2の設定は、以下のような感じです。ModeをSPI Masterにして設定していきます。

imageimage

これは、グラフィック液晶のマニュアルに従い、SCLKは、HighでIdle状態で、クロックの立ち上がりで、SDIのデータを取り込みますから、Clock Edgeの設定は、LowからHighになる、即ち、ActiveからIdleになる時という選択肢を選んだ訳です。

上記の右側のキャプチャは、レジスタの設定がわかるようにしています。

 

そして、いつものように、Generateボタンで、プログラムを生成します。

SPIはどのように使ったらよいかは、生成されたspi2.hとspi2.cのコメントを読むと大体わかります。

初期化は、いつものようにmcc.c内で行われるので、データの書き込み方法がわかれば、プログラムできそうです。

 

まずは、LCDの初期化から。これは、AQM1248Aのマニュアルに記載の例に従って、書いていきました。

その時、コマンド、データ書き込み用のサブルーチンも、例にならって作成しました。

実際のコードは後ほど提示します。

ここで、一番重要なのはPICからLCDへのSPI通信で、命令・データを書き込みを行う関数が必要です。これは、上述のspi2.hの中から、 SPI2_Exchange8bit(uint8_t data)が使えそうだと思いました。

 

初期化ルーチンができたところで、まだ、LCDにデータの書き込みをするようにプログラムは作っていませんが、とりあえず、コンパイルして、動かしてみました。

 

あれれ、、、全然動作しているように見えません。画面にゴミデータすら表示されなかったからです。

 

とりあえず、LCD上に電源がちゃんと印加されているか確認してみたり、SPIのクロックスピードが速すぎて、タイミングがまずいのかなと思って、設定を変更してみたり、上述のClock Edgeの設定が間違っているのかと逆の設定をしてみたり、いろいろやりました。

 

でも、何度か、電源を入れたり切ったりしていたら、ある時、画面にゴミデータが表示されたのですよ。 でも、再度電源を入れ直すと、また表示されなくなります。非常に不安定です。

 

ここで、少し考えました。 今回、/CSを接続例とは異なり、ピン数を減らそうとGND固定にしてしまったのが、いけなかったのではないかと。

 

そこで、MCCにて、RA4 (3ピン)をCSBという名前で追加割り当てを行い、LCDの2ピンと接続しました。

 

そして、コマンド、データを送出する時だけ、CSB=Lとなるようにプログラムを書き換えました。

コンパイルして、PICに書き込み、動作確認です。

 

やったー、成功です。 安定して、画面にゴミデータが表示されるようになりました。

こうなると、がぜんやる気が出てきます。あとは、プログラムを作っていくだけです。 ちゃんと、データを表示するようにプログラムします。

ちゃんと表示できました。以下の写真のような感じです。

DSCN0317

上部がグラフィックLCD、下部がキャラクタLCDです。

 

ここで、ソースを提示しようとしましたが、サイズオーバーになったので、ここでいったん区切ります。

記事へブログ気持玉 / トラックバック / コメント


5灯LEDスタンド運用開始:タッチセンサの調整、消費電流

2016/07/06 20:48

タッチセンサの調整

 

前回の記事で5灯LEDスタンドの製作は完了しました。 (そのはずでした)

あの後、むき出しになっていたスタンドの基部を組み直し、元のようにスタンドの形に戻しました。

 

そして、動作の最終確認を開始しました。

だけど、あれっ、タッチセンサが動作しません。 ただ、物理スイッチの方は、問題なく、動作します。

 

いろいろやってみると、スタンドの足の部分を包み込むように手を乗せると、反応したりします。

でも続けて、同じようにタッチしても反応しません。

非常に反応が悪すぎる感じです。

 

どうも、タッチセンサ回りの環境がふたを開けていたときと変わってしまったようです。

つまり、電気的にみると、PICから見える容量値が変わってしまったのでしょう。

そのため、手でちょっと触っただけでは、例のしきい値を超える容量の違いを生み出せなくなったように思われます。

 

現在、そのしきい値は、デフォルトのままで、100になっています。

これを調整してみたいと思います。 また、スタンドはばらしています。

 

本来であれば、LCDディスプレイと接続して、タッチの有無でどのような値になるか見たいところです。しかし、ご存知の通り、プログラムサイズがぎりぎりの状況で、また、スタンドの中に入れた状態で配線を引き出すのも面倒な作業になるので、実験的に、しきい値を変更させる方法で対応することにしました。

少しいい加減ですが、ホビーなので良しとしましょう。

 

しきい値を50まで下げて見たところ、指で触るとちゃんとスイッチの役割を果たすようになりました。ノイズに弱くなっているかもしれませんが、これでいきます。

 

このしきい値の話とは異なりますが、プログラムを作っている時は気になりませんでしたが、普通に使っていると反応速度が遅いような気がします。500kHz動作だとこんなもんなのかな。

 

まあ、これで、使ってみます。

 

消費電流

ここで、1つすっかり忘れていたことを思い出しました。

 

このスタンドは、単3電池3本使っています。 これで、それなりの期間使いたいと思っています。

そのためには、消費電流を抑える必要があります。その消費電流が、最終的にいくらになったのか調べるのを忘れていたのです。

 

当初以下のように考えていました。

 

8ピンのPIC12F1822を使って、一定時間だけ光らせるようにする。消費電力を極力減らす。
1クリックで、1分間点灯。

 

これで、1年持たせるには、1日どのくらいの回数点灯できるか?

 

アルカリ単3×3本=2000mAhx3=6000mAh の電力があると言われています。

フル点灯時、87mA流していましたから、

6000mAh/(87mA*60s)=4137回 点灯させられる計算をなるはずです。

これは、1日5回点灯させても、2年以上もつ計算となります。


その時、スタンバイ電流=200uAだとすると、1年で、200uA*24hr*365day=1752mAhなので、
上式にスタンバイ電流の分を差し引いて計算すると、(6000-1752)/(87mA*60s)=2929回となります。これは、1年間で点灯できる回数です。1日当たり8回となります。

 

この計算なら、実使用上、十分だろうと思っていたのです。

 

さて、実際にプログラムを完了したこのスタンドは、どのくらいスタンバイ電流がながれているでしょうか、また、明るさの違いでどの位か調べていきましょう。

 

測定してみたところ、大体410uAでした。 上記の見込みより2倍位大きくなりました。

これはタッチセンサを常に動作させているためかもしれません。

 

この場合、1年分のスタンバイ電流は、410uA*24hr*365day=3591mAhとなりました。

そうすると、(6000-3591)/(87mA*60s)=1661回となります。1日当たりにすると、4.5回となります。

私の使い方だと、十分だと思いました。実際には、60sは少し長すぎるので、30sに設定していますし、大体良い感じに仕上がったのではないでしょうか。

 

一方のLEDを点灯した時はどうなるか。

実は、測定できませんでした。なぜか、LEDが一瞬点灯して、すぐに消灯してしまいます。タッチしても、ボタンを押しても、同様です。

 

なぜだろう。。。。。。。

 

一晩考えました。

 

電流測定は、ご承知の通り、回路と直列に測定器を挟まねばなりません。

この時、理想的には、測定器の内部抵抗は0Ωが望ましいですけど、実際はそんなことはないでしょうから、多少なりとも抵抗があるはずです。

 

上記の通り、消灯時は、0.4mA程度しか流していませんから、10Ωの抵抗がついても、4mVの電圧降下にしかなりません。この位は、動作に全く問題ないのでしょう。

 

一方、点灯した時は、90mA近く流すので、10Ωも抵抗がつけば、900mV=0.9Vと、4.5Vの電圧だったとすると、一瞬で、3.6Vまで降下してしまいます。

 

内部抵抗がいくらかはわかりませんが、これが、問題を引き起こしているのではないかと思いました。

 

それなら、適当な非常に小さい抵抗をつなげて、電圧を観測するのがよいだろうと思いました。

しかし、残念ながら、手元に適当な抵抗がなく、断念しないといけませんでした。

 

で、LED点灯時と消灯時で電圧にどんな差が生じているのか見てみました。点灯すると、0.05V下がっていることは測定できました。

しかし、たぶん点灯初期、トランジスタがONした時には、スパイクノイズのような電流が流れ、電圧ももっと降下していたかもしれません。 マルチメータでは検出できませんし、オシロも持っておりませんので、ここまでです。

 

何かいい方法がないかなと、ハードを眺めていたら、ノイズ吸収のパスコンが助けになるかもと、思いつきました。私のハード全然、パスコンつけていませんでしたから。

ちょうど、0.1uFのセラコンがあったので、VDD-VSS間につけてみました。暫定なので、PICのソケットにパスコンを押し込むような形でつなげました。1ピンと8ピンが対象なので、ちょうど差しやすかったので、助かりました。

 

そうしたら、マルチメータを電流計モードで挟んでもPICは、適切に動作するようになりました。

めでたしめでたしです。

 

測定結果は、以下のようになりました。

モード 電流値
スタンバイ時 (消灯時) 0.45 mA
Bright=0 (デフォルトの最も明るい) 82 mA
Bright=1 40 mA
Bright=2 20 mA
Bright=3 (暗い) 9.7 mA

 

Brightの値は、1段階で、点灯時間を半減しさせるようにPWM制御しました。 それに比例するように、電流値が小さくなっています。 非常によい測定結果となりました。

ちゃんとPWM動作できていることが、目で見た明るさ以外の指標で、確認できましたね。

 

フル点灯時の電流が、元のPICを使わなかった時の電流値より小さいのは、SWの代わりに入れたトランジスタ2SA1015と可変抵抗の影響でしょう。

 

そうすると、一番明るい時は、上記の計算とさほど変わりませんから、計算しませんが、1日当たり、1回30秒の点灯を9回行って、1年間、電池交換なしで使える計算となります。

 

輝度を1つ落として、使おうと思っているので、2年程度持つ計算になります。十分ですね。1日に9回も点灯しなさそうなので、もっと使えるだろうと思います。

 

これで、自動消灯機能付きのLEDスタンドの完成としたいと思います。

 

もっと、電池寿命を延ばしたいなら、タッチセンサをやめるというのも1つのアイデアかもしれません。 明るさを維持したまま、できるだけ長い時間使いたいという要求もあるでしょうから。

 

その場合、ボタンが1つだけになるので、モードの変更もボタンで行わねばなりませんが、長押し以外に、ダブルクリック等を使って、複数の状態を得ることができると思いますので、同等の機能を持たせることはできると思います。 その時は、プログラム領域もタッチセンサを削除する分広がりますから、対応は可能になると思っています。 ご興味があれば、実験、工作して見てください。

 

今回1つ入らなかったのは、モード変更した時、その情報をEEPROMに書き込むことです。

情報を書き込めれば、電池交換しても、モードは維持できますが、今回は、電池交換するたびに、モード設定はやり直さないといけません。頻繁に電池交換はないでしょうから、問題となるわけではありませんけどね。

 

では。

記事へブログ気持玉 / トラックバック / コメント


5灯LEDスタンド完成かな 後編

2016/07/03 17:17

前の記事からの続きとなります。

 

main.cのプログラムは、以下となりました。

#include "mcc_generated_files/mcc.h"

#include "main.h"
#include "mcc_generated_files/mtouch/mtouch_button.h"
#include <stdio.h>


/*
* PIC16F1829コントロールLCDに表示
*/
char CursorX, CursorY;

/*
* カーソル位置の設定
* 左上(0,0)から開始
*/
void SetCursor(char x, char y) {
    EUSART_Write(1);
    EUSART_Write(x);
    EUSART_Write(y);
}

/*
* int変数の値をカーソル位置に表示
*/
void DisplayVal(int val) {
    char valStr[10];
    char *str;

    sprintf(valStr, "%d", val);
    str = valStr;
   
    while (*str)
        EUSART_Write(*str++);
   
}

/*
* 文字列をカーソル位置に表示
*/
void DisplayChar(char *str) {
    while (*str)
        EUSART_Write(*str++);
   
}

/*
* LEDの点灯⇔消灯を切り替える
*/
void LEDtoggle() {
    TRISA5 = T2CONbits.TMR2ON; //TMR2オンだったら1でHi-Zに。逆は出力可に。
    T2CONbits.TMR2ON ^= 1; //タイマの停止、開始で対応
}

/*
* LED点滅
*   count数だけ点灯、time:点灯消灯時間(ms)
* timeに255以上設定したいので、intに変更。
*/
void FlashLED(char count, int time) {
    char jj;
    int kk;

    for (jj = 0; jj < count * 2; jj++) {
        for (kk = 0; kk < time / 10; kk++) __delay_ms(10);
        LEDtoggle();
    }

}


/*
                         Main application
*/
void main(void) {
    char pushed; // タッチボタンが押されていたかどうか保持
    mtouch_sensor_sample_t data; // タッチセンサ

    // initialize the device
    SYSTEM_Initialize();
    INTCONbits.TMR0IE = 0;
   
    // When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
    // Use the following macros to:

    // Enable the Global Interrupts
    INTERRUPT_GlobalInterruptEnable();

    // Enable the Peripheral Interrupts
    INTERRUPT_PeripheralInterruptEnable();

    // Disable the Global Interrupts
    //INTERRUPT_GlobalInterruptDisable();

    // Disable the Peripheral Interrupts
    //INTERRUPT_PeripheralInterruptDisable();

    // 変数の初期化
    BtnStatus = 0;
    EUSART_Write(0x0c);
    pushed = 0;
    OnTime = On30s; // OnTimeは、秒単位。初期値は、30s点灯
    Mode = ModeNormal;
    Bright = 0;

    while (1) {
        // Add your application code
        MTOUCH_Service_Mainloop();
        if (MTOUCH_Button_isPressed(Sensor_AN2)) {
            // タッチセンサが押された時の処理
            // モードにより動作が変わる
            if (!pushed) {
                // 初めて押した時だけ処理 (押し続けても連続処理はしないように)
                pushed = 1;
                switch (Mode) {
                    case ModeNormal:
                        LEDtoggle();
                        if (T2CONbits.TMR2ON == 1) {
                            // 点灯したらタイマ2を開始する
                            IntCount = 0;
                            TMR0_Reload();
                            INTCONbits.TMR0IE = 1;
                        } else {
                            // 消灯時は、タイマ2停止
                            INTCONbits.TMR0IE = 0;
                        }

                        break;
                    case ModeSetBright:
                        Bright = (Bright + 1) % 4;
//                        Bright = (Bright + 1) % 5; //0(明)-4(暗)
                        EPWM_LoadDutyValue(0x4f >> Bright);

                        EUSART_Write('0' + Bright);
                        EUSART_Write(10);
                        break;
                    case ModeSetOnTime:
                        if (OnTime == On30s) {
                            OnTime = On1min;
                            FlashLED(1, 300);
                        } else if (OnTime == On1min) {
                            OnTime = On2min;
                            FlashLED(2, 150);
                        } else if (OnTime == On2min) {
                            OnTime = On30s;
                            FlashLED(1, 50);
                        }
//                        DisplayChar("Time=");
//                        EUSART_Write('0' + OnTime / 30);
//                        EUSART_Write(10);
                        break;
                }
            }
        } else {
            pushed = 0; //タッチをやめた(手を離した)
        }

        //長押し判定
        if (LongPush > Long2) {
            if (Mode == ModeSetBright) {
                // モードが変わった時だけ実行
                Mode = ModeSetOnTime;
                FlashLED(2, 100); //100ms間隔で2回点滅
            }
        } else if (LongPush > Long1) {
            if (Mode == ModeNormal) {
                // モードが変わった時だけ実行
                Mode = ModeSetBright;
                FlashLED(1, 100); //100ms間隔で1回点滅
            }
        } else {
            Mode = ModeNormal;
        }

        // 自動消灯タイマのチェック
        if (IntCount / 100 > OnTime) {
            // OnTimeに設定した時間経過したら消灯
            INTCONbits.TMR0IE = 0;
            TMR2_StopTimer(); //消灯
            TRISA5 = 1;
        }

//        data = MTOUCH_Button_Reading_Get(Sensor_AN2);
//        EUSART_Write(12); // cls
        SetCursor(0, 0);
//        DisplayVal(data);
        DisplayChar("Mode=");
        EUSART_Write('0' + Mode);
        EUSART_Write(10);
       
    }
}

黄色くマークした所が主な変更点ですかね。

 

ここからは、細かい調整を使いながら行い、使いやすくしていこうかと思っています。

ということで、これで、本5灯LEDスタンドは完成と言ってもよいかと思います。

 

では、また。

記事へブログ気持玉 / トラックバック / コメント


5灯LEDスタンド完成かな 前編

2016/07/03 17:17

いよいよ佳境に入りました。

 

今回は、PWMを追加して、明るさをコントロールすることに挑戦です。

さて、どうなることやら。

 

前回のプロジェクトをコピーして、TouchLED_v6を作りました。

 

例によって、MCCをOpenして設定をします。

PWMは、CCP (Compare/Capture/PWM)の機能の1つですから、ECCPをクリックして追加してみます。

 

開いたら、ECCP modeをEnhanced PWMにします。そうすると、以下の画面になりました。

image

PWMには、Timer2しか使えないようですね。そうしたら、割り込みタイマは、Timer1とかに変更しないといけませんね。

まず、そちらを片付けてしまします。

いったんECCPを削除してしまいます。

 

Timer2は、8ビットでしたから、Timer0を代わりに使ってみることにします。

タイマ0は、少し使い方が違いますが、まずは、似た感じに設定してみます。

 

以下のようにしてみました。

image

 

TMR2の設定はそのままで、Generateしてみます。

差分の表示がされますが、すべて、前回プログラムするため必要だったものですね。

 

生成されたファイルを見ると、予想された通り、tmr0.c、tmr0.hができています。

割り込みを有効化させるチェックボックスにチェックしておきましたので、interrupt_manager.cにTMR0_ISR()が追加されていました。

 

TMR2_ISR()とは、異なり、その中に直接ユーザ指定のコードを書くようにコメントされていました。

そこに、前回TMR2_DefaultInterruptHandle()内に書いた下記ルーチンをTMR0_ISR()に移します。

 

以下を移動しました。

IntCount++;
if (BtnStatus) {
    // ボタンを押下した時に実行する
    BtnStatus = BtnStatus << 1;
    if (SW_b_GetValue() == 0) {
        // SWが押下状態
        BtnStatus = BtnStatus | 1;
        LongPush++;
    }
    if ((BtnStatus & 0x0f) == 0b0111) {
        // 3回連続押下状態だったら
        LED_b_Toggle(); // LED点灯/消灯
    } else if (BtnStatus == 0) {
        TMR2_StopTimer(); //←ここは間違いです(後述)
        IntCount = 0;
    }
}

 

以下も追加が必要です。

#include "pin_manager.h"
#include "../main.h"

 

コンパイルして、動作を確認しましょう。前回と同じになりました。

MCCのおかげで、簡単にタイマの入れ替えができました。

 

では、もう一度MCCに戻って、TMR2は削除してしまいましょう。

コンパイルしたら、、、あれ、エラーです。

うっかりしていました。プログラムのそこここで、TMR2_StartTimer()と、TMR2_StopTimer()を使っていました。これをTMR0に変更したらいいのだろうと思いましたけど、そんなものはないみたいです。

 

仕方がないので代わりに、    INTCONbits.TMR0IE = 0として、割り込みを止めるしかないようです。

TMR2_StartTimer()→TMR0_Reload();  INTCONbits.TMR0IE = 1;

TMR2_StopTimer()→INTCONbits.TMR0IE = 0;

 

main.c、pin_manager.c、tmr0.cにありました。

 

気を取り直して、コンパイルしました。問題なく生成できました。

それをPIC12F1822に書き込んで動作を確認しました。 問題ありませんでした。

 

これで、MCCから、TMR2が削除されました。

 

ここからが、今回の本題です。

再度、ECCPを追加します。 モードをEnhanced PWMに変更します。

 

設定の前に、Notificationsを見ます。WARNINGが出ている項目を確認します。

3つありました。

image

PWM出力は、LEDのON/OFF制御しているRA5にしないといけませんね。

Pin Managerのウインドウで、ECCP P1Aの行のRA5をクリックします。

そうしたら、NotificationのWARNINGが2つ消えました。

 

残ったのは、Timer2の設定ですね。 削除してしまったTMR2を再度加えます。

そうしたら、WARNINGは消えました。

 

では、ちゃんとECCPの設定をしましょう。

Timerは、Timer2しか選択できないので、そのまま。

PWM Duty Cycleは、まずは100%にしてみます。 ここは、プログラムで変更するので、暫定値ですね。

PWM modeは、singleにします。P1M<1:0>=00ということですね。

PWM pins polarityは、active lowにします。LowになったらLED点灯にしたので。

Steeringは、有効にして、P1AからだけPWMが出力されるようにします。

以下のように設定しました。

image

 

次にTMR2の設定です。10msを周期にしてみました。これで、1秒間に100回点滅を繰り返すことになります。倍速の液晶が120Hzなので、十分だろうと見込みました。

image

ここまでで、設定は完了です。Notification:6となっていますが、WARNINGはありません。

 

この時、ピンは以下のような設定になっていました。

image

 

ここで、Generateします。いつものようにForce Update on Allです。

いつものように差分表示がされました。

生成されたコードより増えた部分は、緑色に塗られています。これは、生成以前のコードに、追加してプログラムを作った部分だと判断されているようで、ほぼ問題ないと思われます。

一方、青く塗られている部分は、生成されたコード自体に手が加わったと判断された箇所のようで、要注意だと思われます。

中には全然関係なさそうなものもあります。例えば、生成コードが

while (1)

{

と2行に渡っているのを、

while (1) {

と1行にしただけとかです。ここは、エディタでTABを押すとそのように整形されるので、そっちに合わせて欲しいですけどね。

また、割り込みの設定が初期時、コメントになっていたのを外した箇所なども青くなります。

 

今回、新しいパターンが現れました。下記のようなものです。pin_manager.cの差分を表示したところです。

image

 

APFCONがマージ後(右側)、0x00にされています。これはまずいです。0x01に変える必要があります。

これは、PWMの出力のP1AをRA5にしたからです。APFCONのbit0は、CCP1の出力をRA2かRA5のどちらかにすることができますが、初期値から変わったからです。

 

そこで、左側の57行の左の矢印を押して、右側のマージ後のファイルを左の設定に置き換えました。

今後、注意したいと思います。もし、これを見落としていたら、また、動かないというバグに悩まされるところでした。

 

ここで、とりあえずコンパイルしてみました。エラーがでます。

これは、従来RA5をGPIOにしていて、単純にOn/Offして、LEDを制御していましたけど、PWMに変更したのに伴い、LED_b_SetHigh()といったものが消えたためでした。

 

新たにソースファイルに加わったepwm.h, epwm.cを開いてみてみます。

初期化は、いいでしょう。mcc.cの初期化から自動的に呼び出されていますから。

EPWM_LoadDutyValue()というのが、輝度変更に有用そうです。

ここでは、PWM出力を制御するものはありませんね。

 

PWMを動かすのは、TMR2でしたから、そちらを見てみます。

TMR2_StartTimer()、TMR2_StopTimer()というのが使えそうです。

Toggleは、どうしましょうね。TMR2ONは読み出しもできるので、レジスタを反転させて対応してみます。

 

main.cと、tmr0.cに修正箇所がありました。

 

でも結果として、これだと、ダメでした。タッチ、SWでLEDが点灯しましたが、消灯しなくなったのでです。

 

うまく止めないと、PWMの出力がLED消灯状態にならなかったからでしょう。PWMの初期化という手もあるでしょうけど、出力をTRISAで制御した方が簡単そうです。

でも、RA5をHi-Zにした時、フローティングさせる訳にはいきませんので、WPUを有効化しました。

 

MCCで、Pin Moduleを開くと、RA5の設定も見えますので、WPUにチェックを入れました。これで、Weak Pull upが有効になり、Hi-Zにした時、VDDレベルとなり、LEDは消灯します。

 

基本的にTRISA5を1か0に設定して、Hi-Zか、PWMの出力とできますが、タイマがカタカタ動いているのも消費電力的に気持ちがよくないので、TMR2_StopTimer()は併用してプログラムしました。

 

これで、コンパイルして、動作を確認してみます。

。。。

ああ、よかった。元の動作と同じになりました。

現在Dutyは100%なので、明るさも前と同じはずです。

 

最後の機能、明るさの設定の取り込みに入ります。

 

先ほど見つけたEPWM_LoadDutyValue()を使ってみます。

最初は、全部が変わるようにmain()の中の初期化のところで設定してみます。

 

50%にしたら、違いが分かるかな。

ここで、どんな値を入れるべきか悩みました。50%とかパーセンテージで入れられると簡単ですけど、CCPRレジスタとして使われる10ビットの値を設定するようです。

 

100%の時、CCPR1L=0x13で、DC1B=0b11でした、つまり、0x4fが最大値ということになります。

 

半分の0x27にしてみました。少し暗くなったどうかという感じでよくわかりません。

極端に0x9にしてみました。今度は、はっきりと暗いというのが分かります。

 

これで、大丈夫そうです。

 

では、組み込んでみます。以前ボタン長押しで、ModeSetBrightというモードを作っておきましたので、そこで、タッチしたら明るさを変更していくようにすれば、良いですね。

 

今確認したら、現在99.7%、2042バイトになっています。たぶん、これ以上何も入れられませんね。とりあえず、デバッグも大体終わりましたから、表示系を削除したら良いですかね。

 

冗長になっているコードを治す必要もあるかもしれません。

 

加えたいのは、次の2行です。

 

                        Bright = (Bright + 1) % 5; //0(明)-4(暗)
                        EPWM_LoadDutyValue(0x4f >> Bright);

 

でも、メモリオーバーでした。最初のBrightの計算式をコメントにしたら、99.9%、2045バイトで、コンパイルできました。

 

プログラムの最適化を図ります。

不要な変数のint→char化をしました。

アルゴリズムの簡素化。

上記の%5という、中途半端な剰余が意外とメモリを食うようなので、2のべき乗の4にしてみました。

 

というようなことをやってみたら、何とか、99.4%、2035バイトと2Kバイトに収まりました。

 

まだ、表示機能は残しています。

書き込んで動作確認をしました。

 

ボタン長押しで、明るさ調整モードに入れ、タッチすると、明るさが変わるのが分かります。

LCDに表示させているBright変数もちゃんと見えています。

 

何とか、2KBに予定していた全部の機能を入れることができました。

 

また、文字数オーバーになってしまったので、続きは次の記事にて。

記事へブログ気持玉 / トラックバック / コメント


続きを見る

トップへ

月別リンク

KazHatブログ/BIGLOBEウェブリブログ
文字サイズ:       閉じる