自由研究2018夏(浦島太郎)

August 16 [Thu], 2018, 10:18
最近、出張が多くて、それも電車での移動が多く、移動中は ほとんど寝てるんですが 読書などしております。
スマホ&Kindleアプリのおかげでかさばらず、手軽に読書が出来るようになりましたし、こんな時じゃないとなかなかじっくり物語なんて読めませんものね。

んで、先日、移動中に小泉八雲(ラフカディオ・ハーン)全集を読んでたんですよ。


その中に「夏の日の夢」という話がありまして、これは筆者が長崎に出張に行った際の紀行文なんですが、宿泊先の洋風ホテルの暑さに辟易して移った旅館で、女将さんや女中さんのおもてなしをたいそう気に入ったらしく、龍宮城に例えて浦島太郎の話に触れるんですね。

で、その中でこんな行がありまして

ところで、天皇の公式の記録にはつぎのように書かれている。「雄略天皇の御世の二一年[#原文のまま。日本書記には二二年とある]に、丹後国餘社郡水之江の住人、浦島子、釣り舟にて蓬莱山へ行く。」この後、三一代の天皇の間に記事はない。―― それは五世紀から九世紀の間である。それから、また、この記録には、「後淳和天皇の御世、天長二年、浦島太郎、帰る。また出発するも、その行方は誰も知らず」とある。

小泉 八雲. 『小泉八雲作品集・54作品⇒1冊』【さし絵つき】 (Kindle の位置No.1557-1562). Yakumo Koizumi Complete works. Kindle 版.


ん?浦島太郎って日本書紀に原典があるの!??
釣り船で仙人の世界に行った漁師が400年ぶりに帰ってきたと。
その具体的な年まで?

気になったので日本書紀を調べてみました。



なるほど、浦島太郎失踪についてこうあります。

巻第十四 雄略天皇(ゆうりゃくてんのう)、大泊瀬幼武天皇(おおはつせのわかたけのすめらみこと)
(中略)
二十二年 秋七月、丹波国与謝野郡の筒川の人、水江浦嶋子が、舟に乗って釣りをしていた。そして大亀を得た。それがたちまち女となった。浦島は感動して妻とした。二人は一緒に海中に入り、蓬莱山に至って、仙境を見て回った。この話は別の巻にある。

宇治谷 孟 (翻訳)、日本書紀(上)全現代語訳 (講談社学術文庫) 文庫 – 1988/6/6


雄略天皇在位がはっきりとは特定できませんが、有力な説の西暦478年7月(太陽暦では9月頃でしょうか)、船で釣った大亀が女性に变化し、娶って共に仙人の山に行ったと。
ただし、詳細は別の巻(←参考文献のこと)にあると。。。。
これ、肝心なところが書かれてねぇよ。別の巻ってなんだよ orz。

そもそも、日本書紀は神代〜持統天皇までの各天皇の治世にあった事件を綴ったもので、今で言うニュースダイジェストのようなもの。
浦島太郎行方不明事件は「百済消滅」と「雄略天皇崩御」という超ビッグニュースに挟まれてひっそりと書かれています。(ニュースバリューとしてのギャップが大きすぎるような気がしますが、それはとりあえずおいといて)

で、日本書紀最後の持統天皇が第41代。
浦嶋太郎が帰ってきたとされる時の淳和(じゅんな)天皇はそのずっと後の第53代天皇。
そりゃ載ってるはずないやんけwww頼むわ〜八雲さんwww


しかたがないので、別巻とされる丹後国風土記を探してみました。

なぜ、この別巻が丹後国風土記なのかというと、鎌倉時代に卜部兼方(うらべ・かねかた)が著した『釈日本紀』(しゃくにほんき、1300年頃の成立)という日本書紀に関する解説書の中(巻第十二)に「丹後国風土記にいう」と伝説の逸文が紹介されているからだそうです。1)

残念ながら丹後国風土記は逸文ですのでオリジナルを見ることは出来ません。
引用文のみが現存し、現在は国立国会図書館が所蔵。インターネット上に公開している資料となっています。



漢文ですが、根性がある人は読んでみてください。
(一応全部目を通してみましたが、正直、どこからが浦島太郎の原典に当たるのかさえ判りませんでした。)

これまた参考文献によりますと、丹後国風土記はこのような前置きから始まるそうです。1)

与謝郡、日置(ひき)の里に筒川という村があり
ここに日下部首(くさかべ・おびと)たちの先祖である筒川の嶼子(しまこ)という人がいた。
姿容が非常に優れとても風流な彼は、所謂、水江の浦の嶼子という者であった。
この話しは旧宰、伊預部馬養連(いよべ・うまかい・むらじ)の記したものに少しも背く内容のものではない。


また、物語の本文に関しては、こちらの記事を参考にさせていただきました。
(筆者の意訳で盛りまくっているようですが、物語としては辻褄があっていて面白かったので。)

日本天文教育普及委員会〜天文教育 2010 年 11 月号(Vol.22 No.6)〜投稿、浦島太郎とかぐや姫
〜丹後国風土記と竹取物語の語ること〜作花一志(京都情報大学院大学)



 丹後の国、与謝の郡、日置の里、筒川の村に「筒川の嶼子(しまこ)」別名「水江の浦の嶼子」という容姿端麗で優雅な男がいました。
 ある日嶼子は、一人で大海に小船を浮かべて釣りをしていましたが、三日三晩しても全く釣れませんでした。ところがついに五色の大亀が釣れ、船上に上げて眺めていると眠くなっていつの間にか寝てしまいました。
 しばらくして目が覚めると、亀が美しい乙女に姿を変えていました。ここは陸から離れた海の上、「どこから来たのですか。」とたずねると、乙女は微笑みながら「あなたが一人で釣りをしていたのでお話ししたいと思い、天上仙家から風雲に乗って会いきました。」と言います。そして天地日月の果てまでと嶼子のそばにいたいとモーレツに求愛し、海の彼方にある蓬山(とこよ)の国へ誘います。初めは疑っていた嶼子も彼女の熱意(というより誘惑)に負けて、一緒に行くことにしました。嶼子は船をこぎ始めるとすぐに眠ってしまいました。
 まもなく宝石をちりばめているように光り輝く大きな島に着きました。そこはこれまでに見たことがない景色でした。
大変高くてきれいな宮殿があり、楼閣はすべて光輝いているように見えます。二人は手を取り合ってゆっくりと歩んでいくと、一軒の立派な屋敷の門の前に着きました。
 乙女は「ここで待っていてください。」と言って中に入っていきました。門の前で待っていると、7人の子供がやってきて「この人は亀姫様のお婿さんになる人だ。」と語っています。そして、次に8人の子供がやってきて、また「亀姫のお婿さんはこの人だ。」と話しています。嶼子は乙女の名は亀姫で、この宮殿のお姫様だと知りました。
 しばらくして、乙女が出てきて「この7人の童は昴星で、8人の童は畢(ひつ)星ですから、ご心配なく。」と説明して門の中へ案内しました。

(ここから先は私たちの知っている童話とほぼ同じですが、最後が違っています。)

 嶼子は亀姫と結婚して、何不自由ない楽しい日々をすごしました。
 ところが3年経って故郷へ帰りたくなり、妻・亀姫にそのことを話すと、彼女は非常に悲しみ「永遠の誓いをしたのに、あなたは私一人を残して帰ってしまうのですね。」と涙を流します。しかしついに「私のことを忘れないで、また会いたいと思うのなら決してふたを開けてはなりません。」と言って玉匣(たまくしげ)を渡します。
 亀姫の両親に別れを告げ船に乗って目を閉じると、たちまちのうちに故郷の筒川に着きました。ところがそこにはかつての村の姿がなく、見たことのない景色ばかり、しばらく歩いて、村人に水江の浦の嶼子の家族のことを聞いてみました。すると不思議そうな顔をして「今から300年前に嶼子という者が、海に出たまま帰ってこなかったという話を年寄りから聞いたことがあるが、あなたはどうしてそんなことを急に尋ねるのですか?」という答です。嶼子は村を離れていたのは3年間だと思っていたのですが、実は300年も経っていたと知り、途方にくれてしまいました。
 さまよい歩くこと1か月、再び妻に会いたくなり、約束も忘れて持っていた玉匣のふたを開けてしまいました。すると中から芳(かぐわ)しいにおいが天に流れていってしまいました。ここで我に返って約束を思い出しましたが、すでに遅かったのです。彼は首をめぐらしてたたずみ、涙にむせび、うろうろ歩き回るばかりでした。

そして次の歌を詠みました。

 常世べに 雲たちわたる 水の江の
 浦嶼の子が 言持ちわたる

遙か彼方の芳音の中から亀姫の歌が、

 大和辺に 風吹き上げて 雲放れ
 退き居りともよ 吾を忘らすな

嶼子は恋慕に耐えきれずに歌います。

 子らに恋ひ 朝戸を開き 吾が居れば
 常世の浜の 波の音聞こゆ

これについて後世の人はこう歌いました、

 水の江の 浦嶼の子が 玉くしげ
 開けずありせば またも会はましを
 常世べに 雲立ちわたる たゆ***(***の部分は不明、多由女という説がある)
 雲はつかめと 我ぞ悲しき

物語はここで終わっています。


とりあえず、乙姫は宇宙人あるいは未来人で、大きな亀は宇宙船、浦島太郎は星まで行ったタイムトラベラーというSF的な視点は除いて考えてみましょう。

物語の舞台になっているのは丹後半島。日本海側で大きな亀?
古代の日本は今とよほど気候が違っていたのか、南の民族の間で語り継がれていた伝承が日本海側の最果てにたどり着いたのか?

そういえばワニ(あるいはサメ)の群れが出てくる話で有名な因幡の白うさぎはやはり日本海側の出雲(島根〜鳥取)の伝承。
島根といえば神代では根の堅州国、スサノオ、出雲神話、オオクニヌシ・・・ヤマト朝廷とは異なる豪族が勢力をもっていた地方です。

また、当時**子と名がつく人はそれなりに身分が高い人で、それからすると浦島太郎は貧乏な漁師ではなく、豪族の一人であったとも推測されるそうです。1)
それなら日本書紀に登場した理由も分かるような気がします。

日本書紀は奈良時代に舎人親王らの撰で、各地の風土記も取り込んで編選され、養老4年(720年)に完成とされています。
そこに鎌倉時代の権力者の都合と解釈で注釈が追加され、その際に丹後国風土記が加えられて。。

大きな亀が比喩だとすると、亀は何かのシンボルマーク?
あるいは亀にゆかりのある一族にまつわる話なのかもしれませんね。
謎は深まります。

※参考文献
1) 中原中也とダダイズム、京都時代 日本史探訪・オノコロ共和国 〜浦島太郎は「竜宮」へ行ったのか?〜








カーオーディオを部屋で使ってみた(その1)

July 30 [Mon], 2018, 11:03
これまでいくつかの中華製デジタルアンプを試してみた感想。

音量調整をプリアンプのゲインでやってて、しかも反転増幅回路だったりする。
トーンコントロールも反転増幅なので、ダイレクトモードに切り替えると位相がひっくり返る。
パワーアンプ出口側のローパスフィルタに難があり、高音が再生できない。
EMCフィルタの係数がデタラメでノイズ出まくり。
ディスクリート部品のはんだ付けでまともなのはほぼ無い。
熱対策やアースが妙に雑。
基盤のパターン設計がまずいのか?時々ノイズが乗る。

部品や回路を見直して改造しまくっても結局どこかで壁にあたってしまう。
(そもそも、ちゃんとした設計がなされていれば必要の無い改造がほとんどなんだけど。)

かかる手間はプライスレス(基本無料)だけど、カットアンドトライで使う部品の種類が少なくなく、歩留まりが悪いのでコスパはよろしくない。
使ってる材料そのものに起因するトラブルも多く、寿命が短かったり不定期のトラブルが出たりで、常に何らかのウミを抱えてだましだまし使っているというのが実態ではなかろうか。
別基盤をおこして完全に作り変えてしまう方法も考えはしたんだけど、、、

結論、値段なりのクオリティと割り切れるし、ホビーとして中身をいじるのはなかなか楽しいが、安定した状態で普通に使うにはちょっとしんどい。

次の機体を物色している最中に、中華製アンプって中身はもともとカーオディオ用のパワーアンプなんだから、いっそカーオーディオを転用したほうが早くね?ってことに気づく。(今更って言うな)

思い立ったが吉日なので、早速、手頃な中古品をゲットした。
Carrozzeria DEH-480
CDが振動で音飛びするというジャンク品。ヤフオクで約1500円+送料。
2013年の製品で現在は生産中止。同シリーズのローエンドモデルDEH-380は現在も販売中。
1DINサイズと小型ながら、CDはもちろん、AUXポートあり。mp3直接再生可能。USBからipodが使えるようなので、今回の用途にはぴったりだ。
今、軽のほうで使ってるMVH-5100と互換部品も多いようで、本体が壊れても代替品がすぐに手に入りそうだ。

カーオーディオなので、4スピーカーをフルに使うと100W。
当座は2スピーカーだからそんなに電力は必要ないが、将来的にサラウンドスピーカー導入の予定なので、電源を新規に用意する。
ユニットと併せて2DINくらいの箱に収まりそう。
それでも、うちにあるONKYO製ミニコンポよりずいぶん小さい。

ってことで、電源はTDKラムダ製RWS150B-12、DC12V150W
100Wにしなかったのは、ディレーティングを考慮した安全率。大は小を兼ねる?
(っていうのはウソで、100Wだと思って手にとったのが150Wだとレジで気がついたが入口まで戻るのがめんどくさかった。(*´∀`*) ※秋月は店の入口のところに電源がおいてあって、電子部品は一番奥にあり、奥のレジが比較的空いている。)

電源スイッチについては、ロッカスイッチやオルタネートスイッチでもいいが、
せっかくだからON/OFFをワンタッチで操作出来るように電源回路を作ってみよう。
ロジックICでモメンタリ→オルタネート化回路を組んでみた。
カーオーディオのAccの要求電流がどれくらいかわからないので、念の為にMOS-FET(30A)を通してあるけど、多分それほど大きな電流は必要ない。
とりあえず、これでボタンを押す毎にAccのONとOFFが切り替わる。


バラックで動作確認中


仮組みで音出しテスト中。
分解清掃後、FMアンテナ(JASOプラグ)を引き込んで、チューナー、CD、USBメモリ、iPod、AUX全部試して異常なし。
ラウドネス、バスブーストなど、面白いくらいにイコライザーが効く。
中華アンプに慣れた身にはなんだか新鮮。(だって改造しなくてもちゃんと音が出るんだぜww)
調子に乗ってリモコンまで用意した。


必要なのは多少のはんだ付けと配線結線の技能だけ。本体取説があったのでここまではあっという間に完成した。
次はケースを考えよう。


ここまでに使った部品

※秋月電子さんで調達
スイッチング電源、RWS150B-12、AC85〜265V/DC12V13A、TDKラムダ、1個
2P−3Pアース付ACコード、SH-015A+SH-006、1個
LED付押しボタンスイッチ(青)、PB01-11A-LBL-N-3M、1個
プッシュターミナル(端子台)、MPT-3G(A)、2個
基板用コネクタ、B2B-XH-A(LF)(SN)、4個
XHコネクタ付リードハーネス、XH、2P,120mm、4個
片面ガラス・ユニバーサル基板、Cタイプ めっき仕上げ (72x48mm) 日本製、1個

※千石電商さんで調達
CMOSロジックIC、TC4013BP、1個
カーアンテナプラグ、MP-126M、マル信無線電機、1個

※アマゾンで購入


※他、在庫引当
アンテナ線とターミナル、1式
スピーカーターミナル用圧着端子、8個
電解コンデンサ、セラミックコンデンサ、抵抗、ユニバーサル基板等、1式

ジェネリックPickit3

July 05 [Thu], 2018, 11:06
”ジェネリック”といえば聞こえはいい。
多分Microchip社の許可なんてとってないだろうから、所謂海賊版か?
ついに悪魔に魂を・・いや、取説で回路図公開してるし、Arduinoみたいに互換機として売っていいのか?

壊れた純正Pickit3。
一旦は修理するも、しばらく使っていたら今度はVDD周りが壊れたようで、いよいよ利用が出来なくなった。
故障の原因はCLKをプルアップしてしまったことと推測。
CLKのゲートICに逆電圧がかかり損傷、VDDがプルアップ抵抗と内部のプルダウン抵抗と壊れたゲートICなどを通ってオーバーカレントで損傷ってなことではなかろうか。しらんけど。(´・ω・`)
今更恨み言を言ってもしかたがないが、ビギナ向けの本ならもうちょっと安全性は考慮しといて欲しいのう。(´・ω・`)
だがしかし、結果は全部自分持ち。
他人の回路図を鵜呑みにした自分が悪い。
電子工作っちゃそういうもんだと自分に言い聞かせる。

すぐにPickit4を購入したので、たちまち困ってはおらず、また、バックアップ用だと使用頻度も高くないので 値段の安い 互換品を購入してみた。
(まぁ、なんかあってもネタにはなるし。)


6/24 午後発注、6/25 発送の連絡、7/6までに到着予定(正味2週間)
輸送はいいが、税関で止まりそうだからこの納期では無理だろうと思っていたら7/3に到着した
素晴らしい。

毎度、掲載されてる写真と違っても放置され続けるのは文化的なものだと思いたい。
これが日本企業ならフルボッコにされるところだ。
幸いなことにWマークが入った旧型?
付属のケーブルが赤かった!ラキー━━━━(゚∀゚)━━━━!!
なんか早そう。そう、通常の3倍くらい。


純正と比較してみた。
当然ながらMicrochip社のロゴが無い。
大きさは全く同じ。
ついでにいうとパネルカットやLEDの配置も同じようなので、フロントカバーだけ付け替えとけば・・・いや、やめとこう。


USBにつなぐとPickit3と認識され、MPLAB X からファームウェアのアップデートも無事出来た。
12F683に何度か読み書き。問題なさそう。
これからもちょいちょい使ってみよう。

I2C 16bit ADコンバータ MCP3425(その2)

June 24 [Sun], 2018, 15:10
ソースを載せると記事が無駄にながくなってしまったので、2つに分けました。
動作確認中の映像です。


 
以下プログラムのソース。
実行には別途 i2c_lib2 と AQM1602XA_Lib が必要です。
I2Cバスの割付デバイスが変更されましたので、過去発表した同名のライブラリは今回に合わせて更新されて
ます。



/********************************
 * File:   MCP3425_Sample.c
 * Author: Kazui Okumori
 *
 * Created on 2018/06/21, 12:00
********************************/


// PIC12F683 Configuration Bit Settings

// 'C' source line config statements

// CONFIG
#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = ON       // MCLR Pin Function Select bit (MCLR pin function is MCLR)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown Out Detect (BOR enabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include <string.h>
#include "i2c_lib2.h"
#include "AQM1602XA_Lib.h"
#include "MyLCD.h"
#include "MCP3425_Lib.h"


//**********************************************************************************//
//  定数の設定
//**********************************************************************************//
#define SDA GP5
#define SCL GP4
#define TRISSDA TRISIO5
#define _XTAL_FREQ  1000000 // クロック周波数設定

//**********************************************************************************//
//  グローバル変数
//**********************************************************************************//
const unsigned char Table[]= {
    "MCP3425 "
    "16-Bit A/D Converter    "
    "The Master is PIC16F683 "
    "I2C interface."
};
unsigned char Msg1[] = "00000V";
unsigned char Msg2[17];
unsigned char Msg3[17];
unsigned char i,j;
int Value;

//**********************************************************************************//
//  関数プロトタイピング
//**********************************************************************************//
void WriteCharacters(unsigned char count);  // タイプライタのように一文字づつゆっくり書く

void main(void) {

    //OPTION REGISTER 設定、PIC12F683 Data Sheet による
    OSCCON = 0b1000000;             // Internal Fosc=1MHz=1usec
    ANSEL   = 0b0000000;            // すべてデジタルに設定
    CMCON0  = 0b00000111;           // コンパレータ無効化
    WPU     = 0b110000;             // プルアップビット指定(1=プルアップ)
    TRISIO  = 0b001111;             // GP0,1,2,3入力、他は出力設定(1=入力)

    /* OPTION_REG: OPTION REGISTER  */
    nGPPU   = 0;        // GPIO Pull-up Enable bit
    INTEDG  = 0;        // Interrupt Edge Select bit
    T0CS    = 0;        // Timer0 Clock Source Select bit
    T0SE    = 0;        // Timer0 Source Edge Select bit
    PSA     = 0;        // Prescaler Assignment bit
    
    GPIO = 0b110000;    // 初期のI/Oセット
    
    lcd_init();                 // 画面初期化
    
    while(1) {
        
        ClearDisplay();
        j=0;
        SetDDRAMAddress(0x00);
        for(i=0; i<16; i++) {
            WriteDataToRAM(Table[j]);
            delay_100ms(1);
            j++;
        }
                                                                                 
        SetDDRAMAddress(0x40);
        for(i=0; i<16; i++) {
            WriteDataToRAM(Table[j]);
            delay_100ms(1);
            j++;
        }
        delay_100ms(10);
        ClearDisplay();
        
        // 16bit
        ConfiglationAD(0b1000);     // 16bit,Gain=1V/V

        ClearDisplay();
        delay_100ms(5);
        SetDDRAMAddress(0x00);
        strcpy(Msg3,"16bit[dec]");
        lcd_str(Msg3);

        for (i=0; i<50; i++) {
            Value = GetADValue();
            Int2Ascii(5,Value,Msg2);
            SetDDRAMAddress(0x40);
            lcd_str(Msg2);
            delay_100ms(1);
        }
        
        // 14bit
        ConfiglationAD(0b0100);     // 14bit,Gain=1V/V
        
        ClearDisplay();
        delay_100ms(5);
        SetDDRAMAddress(0x00);
        strcpy(Msg3,"14bit[dec]");
        lcd_str(Msg3);
        
        for (i=0; i<50; i++) {
            Value = GetADValue();
            Int2Ascii(5,Value,Msg2);
            SetDDRAMAddress(0x40);
            lcd_str(Msg2);
            delay_100ms(1);
        }
        
        // 12bit
        ConfiglationAD(0b0000);     // 14bit,Gain=1V/V
        
        ClearDisplay();
        delay_100ms(5);
        SetDDRAMAddress(0x00);
        strcpy(Msg3,"12bit[dec]");
        lcd_str(Msg3);
        
        for (i=0; i<50; i++) {
            Value = GetADValue();
            Int2Ascii(5,Value,Msg2);
            SetDDRAMAddress(0x40);
            lcd_str(Msg2);
            delay_100ms(1);
        }
        
        // 16bit 1V/V
        ConfiglationAD(0b1000);     // 16bit,Gain=1V/V

        ClearDisplay();
        delay_100ms(5);
        SetDDRAMAddress(0x00);
        strcpy(Msg3,"16bit 1V/V[dec]");
        lcd_str(Msg3);

        for (i=0; i<50; i++) {
            Value = GetADValue();
            Int2Ascii(5,Value,Msg2);
            SetDDRAMAddress(0x40);
            lcd_str(Msg2);
            delay_100ms(1);
        }
        
        // 16bit 2V/V
        ConfiglationAD(0b1001);     // 16bit,Gain=1V/V

        ClearDisplay();
        delay_100ms(5);
        SetDDRAMAddress(0x00);
        strcpy(Msg3,"16bit 2V/V[dec]");
        lcd_str(Msg3);

        for (i=0; i<50; i++) {
            Value = GetADValue();
            Int2Ascii(5,Value,Msg2);
            SetDDRAMAddress(0x40);
            lcd_str(Msg2);
            delay_100ms(1);
        }
        
        // 16bit 4V/V
        ConfiglationAD(0b1010);     // 16bit,Gain=4V/V

        ClearDisplay();
        delay_100ms(5);
        SetDDRAMAddress(0x00);
        strcpy(Msg3,"16bit 4V/V[dec]");
        lcd_str(Msg3);

        for (i=0; i<50; i++) {
            Value = GetADValue();
            Int2Ascii(5,Value,Msg2);
            SetDDRAMAddress(0x40);
            lcd_str(Msg2);
            delay_100ms(1);
        }
        
        // 16bit 8V/V
        ConfiglationAD(0b1011);     // 16bit,Gain=4V/V

        ClearDisplay();
        delay_100ms(5);
        SetDDRAMAddress(0x00);
        strcpy(Msg3,"16bit 8V/V[dec]");
        lcd_str(Msg3);

        for (i=0; i<50; i++) {
            Value = GetADValue();
            Int2Ascii(5,Value,Msg2);
            SetDDRAMAddress(0x40);
            lcd_str(Msg2);
            delay_100ms(1);
        }
    }
}

void WriteCharacters(unsigned char count) {
    unsigned char i;
    for(i=0; i < count; i++) {
        WriteDataToRAM(Table[i]);
        delay_100ms(2);
    }
}


ライブラリヘッダファイル
/********************************
*  デルタシグマA/Dコンバータ用ヘッダファイル
*  for MCP3425 Ver1.0
*  Fosc = 1MHz
*  File:   MCP3425_Lib.h
********************************/

#define _XTAL_FREQ  1000000 // クロック周波数設定

/** 関数プロトタイピング **/
void ConfiglationAD(unsigned char para);
//void GetDataAD(unsigned char *Buffer,unsigned char CNT);
int GetADValue(void);




ライブラリ本体
/********************************
 * File:   MCP3425_Lib.c
 * Author: Kazui Okumori
 *
 * Created on 2018/06/19, 19:36
********************************/

#include <xc.h>
#include "i2c_lib2.h"
#include "MCP3425_Lib.h"

/*******************************
* コンフィグレーション設定
*******************************/
void ConfiglationAD(unsigned char para) {
 I2CStart();                 // スタート
 I2COut(0xD0);               // スレーブアドレス
    para = para | 0b10010000;   //Ready Bit,Conversion Mode Continuous
 I2COut(para);    // コマンド出力
 I2CStop();                  // ストップ
    __delay_ms(1);    
};

/*******************************
* 変換データ取得
*******************************/
//void GetDataAD(unsigned char *Buffer,unsigned char CNT) {
//    unsigned char i;
//    
// I2CStart();                 // スタート
// I2COut(0xD1);               // スレーブReadMode
//    for (i=0; i<CNT; i++) {
//        Buffer[i] = I2CRcv(0);
//    };
//    Buffer[i] = I2CRcv(1);
// I2CStop();                  // ストップ
//    __delay_ms(1);    
//};

/*******************************
* 16bitAD変換→int
*******************************/
int GetADValue(void) {
    int Value;
    unsigned char i;
    char Buffer[3];
    I2CStart();                         // スタート
 I2COut(0xD1);                       // スレーブReadMode
    for (i=0; i<2; i++) {
        Buffer[i] = I2CRcv(0);  // 0=Ack
    };
    Buffer[i] = I2CRcv(1);      //1=Nak
 I2CStop();                  // ストップ
//    Buffer[0] = 255;
//    Buffer[1] = 255;
    Value = ((int)Buffer[0] << 8) | Buffer[1];  //char→int変換

 return(Value);    // 受信データを戻す
};

ちょこっと改良版のMyLCD.lib
/********************************
*  16*2液晶表示器用ヘッダファイル
*  Fosc = 1MHz
*  File:   MyLCD.c
*
********************************/

/** 関数プロトタイピング **/
void LcdLineClear(unsigned char cmd);   // 1行消去 0=1行目,0<>2行目
void Int2Ascii(char digit,int data,char *buffer);  // int整数からASCII文字に変換



ライブラリ本体
/********************************
*  16*2液晶表示器ライブラリ
*  Fosc = 1MHz
*  File:   MyLCD.c
*
********************************/

#include <xc.h>
#include "i2c_lib2.h"
#include "AQM1602XA_Lib.h"
#include "MyLCD.h"

/*******************************
* 1行クリア
*******************************/
void LcdLineClear(unsigned char cmd) {
    char i;
    if (cmd == 0x00) {
        SetDDRAMAddress(0x00);  //SET DDRAM Address = 00h        
    }
    else {
        SetDDRAMAddress(0x40);  //SET DDRAM Address = 40h        
    }
    for(i=0; i<16; i++) {
        WriteDataToRAM(0x20);   //Fill by " "
    }
 __delay_ms(1);
}

/*******************************
* int整数からASCII文字に変換
* Int2Ascii(変換桁数,データ,書き込み先);
*******************************/
void Int2Ascii(char digit,int data,char *buffer) {
    char i;
    int j;
    digit = digit++;    //±の符号を入れる場所を確保
    buffer += digit;    //最後の数字位置
    if (data <= 0) {    //マイナスの場合
        j = ~data;
    }
    else {              //プラスの場合
        j = data;
    }
    for (i=digit; i>0; i--) {   //変換は下位から上位へ
        buffer--;               //ポインタ-1
        *buffer = (j % 10) + '0';    //ASCIIへ
        j = j / 10;             //次の行へ
    }
    if (data <= 0) {    //マイナスの場合
        *buffer = '-';
    }
    else {              //プラスの場合
        *buffer = '+';
    }
}



I2C 16bit ADコンバータ MCP3425(その1)

June 23 [Sat], 2018, 8:00
MCP3425(16Bit ADC I2C 基準電圧内蔵)搭載モジュール
形:AE-MCP3425,¥250
秋月電子さんで販売されてるA/Dコンバータ。Microchip社製のチップとDIP化モジュールのセット。
最大16bitの分解能で電圧を測定できる。

今回はポインタ変数を駆使してint→Ascii変換をするので、ここで簡単にポインタ変数の使い方を整理して
おこう。
※ポインタ変数の一般的な使い方
1.ポインタ型変数を宣言する
2.ポインタ変数にターゲットとなる変数のアドレスを代入する
3.ポインタ変数を通常変数モードに切り替えて、ターゲットの変数が割り付けられているメモリを直接操作
する

int main(void)
{
    int *p     //ポインタ型変数を宣言する
    int i;       //アドレスを知りたい変数
    p = &i;    // ターゲットの変数のアドレスを代入する
    *p = 10; // pに格納されたアドレスのメモリに10を書き込む
    printf("p = %d\n",p);
    printf("i = %d\n",i);
    return 0;
}

実行結果
p = 10
i = 10

シーケンサ屋さん的に例えると、ポインタってのはシーケンサでいうところの関節指定命令みたいなもんだと
思う。
シーケンサの場合、この間接指定を使いこなせるようになれば飛躍的にプログラムの容量を節約出来き、より
高度な制御が可能になる。
三菱電機Qシリーズでは
0 LD SM400
1 MOV K100 Z0
3 MOV K10 D0Z0

とすればD100に10が入る。
ただし、この場合、アドレスはK100 Z0という形でに手動で指定してるので、これを自動で取得するのがポイ
ンタだ。

C言語では変数の頭に&をつけるとその変数のアドレスが取得できる。
また、ポインタ変数の頭に*をつけると保持したアドレスのメモリとして操作出来る。
これは一見 *p=i となっているように見えるけど、*p は i のメモリそのものと考えるべきである。

ちな、この接頭の&をアドレス演算子、*を関節演算子と呼ぶそうだがこの名称から役割が想像できたら大したも
のだと思う。

ブレッドボードで組んでみた。
右端のトリマ2つで±3.3VをAD変換器に印加できる。


回路図はこちら。(ただし、難あり)


見る人が見ればすぐに解ると思うのだが、ICSPのCLKがI2CのSCLに干渉する。
Pickit3だと問題はない Pickit3もCLKはピックアップ禁止だが動いてた。
Pickit4は待機中にCLKがローインピになってしまうらしく、書き込む都度コネクタを外さないとI2C通信が出来
ない状態に陥ってしまう。
これはかなりめんどくさい。

で、対策した回路がこちら。
これならコネクタの抜き差しすること無く動く。
ソフトもこれに合わせて修正せねば。


ってか、 そもそもPGC/PGDはプルアップ禁止だった。
Pickit3で動いていたのはたまたまだったようだ。
早めに気づかせてもらえて良かった。サポートのおかげ。



教科書はこちら。
基本的な動作を含め、プログラムソースを大量に流用させていただいています。(多謝)






P R
Find more about Weather in Kobe, JP
Click for weather forecast
Find more about Weather in Kluang, MS
Click for weather forecast
Find more about Weather in Penang, MS
Click for weather forecast
プロフィール
  • プロフィール画像
  • アイコン画像 ニックネーム:かずい
  • アイコン画像 性別:男性
  • アイコン画像 現住所:兵庫県
読者になる
since 2006.11
無料で使えるプチアクセスカウンター中古マンション地図姫
カスタム検索

ご来訪ありがとうございました。
お帰りはぜひこちらからどうぞ。
↓↓↓↓↓↓↓

  にほんブログ村 バイクブログ カワサキへ
にほんブログ村
2018年08月
« 前の月    |    次の月 »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31