もくじ
./作品集
PSoCのSleep機能と、ユーザモジュールとしてのSleepTimerの関係がいまいちよくわからなかったので、いろいろ試したりデータシートを熟読したりして、やっとわかった。
以上から、SleepTimerユーザモジュールを使うと、一定時間待つ(SleepTimer_TickWait())ことなどはできるが、CPU自体がSleepモードに入るわけではないので、消費電力は通常時と同じ。
普段Sleepモードに入れておいて定期的に起こすには、以下の手順をふめばよい。
PSoCをMiniProgで、XRES(リセット端子)を使わずに電源のON/OFFを書き込みから切り替えて書き込みを制御するPowerCycle方式を使うとき、電源ラインに大きめのパスコンがついていると、電源電圧の立ち上がりが急峻にならず、うまく書き込みが開始できないことがあるようだ。これの解決策ってあるのか?パスコン/電源系を切り離せるようにするしかないのか?ダイオードをはさむ、というのは現実的ではないよなあ。
高速オペアンプ(LMH6639)でボルテージフォロアをつくってみたら、見事に発振(5MHzぐらい)した。定石にしたがって、VoutからV-へのフィードバックを、直結ではなく1kΩにしてみたら、だいたい大丈夫そう。100Ωでは発振は止まらなかった。もうちょっと大きくすると、もうちょっとよくなるのかな。
以前調べたことがあったが、どうも間違いがあったっぽいので補足訂正。
ちょっとほしいかも。C328と似ているが、ボーレートが高くできる。
http://www.4dsystems.com.au/prod.php?id=75
簡単に調べてみた。
SysClk | CPU | Analog | Icc[mA] | |
(1) | 6MHz | 1/256 | On | 1.74 |
(2) | 6MHz | 1/2 | On | 1.96 |
(3) | 24MHz | 1/256 | On | 3.09 |
(4) | 6MHz | 1/256 | Off | 1.35 |
(1)-(4)の0.4mA程度が、アナログブロックの消費電流、ということになる。
PSoCでSleepに入ると、PWMも止まるようだ。元クロック(SYSCLK)が止まるのか?
圧電ブザーをPSoCのI/Oポートにつけて駆動してみる。周りの関係で、0=Weak, 1=Strong、で駆動(Pull-downと同じ)するが、どうも0にうまく落ちないことがある。具体的には、そのピンの値を読もうとすると、0に落ちきらないことがあるようだ。圧電ブザーの静電容量はだいたい0.01uF程度のようだが、これの放電が間に合わないのだろうか。とりあえず100Ωぐらいの抵抗を圧電ブザーに並列につけて、強制的に放電させると、大丈夫っぽいが、詳しい原因がよくわからない。
文献によると、Sonyのものはキャリア周波数が40kHz、というものが散見されるのだけど、手持ちのマルチフォーマット対応リモコンでSony規格の信号を出すときは、他の規格と同じ38kHzのようだ。受信機側のバンドパスの帯域しだいだが、少なくとも38kHzで大丈夫な機器が多い、ということか。
INT_CLR0のbit5がGPIO割り込みの割り込みフラグで、GPIO割り込みがかかると、これが1になる。
GPIO割り込み中に、次のGPIO割り込みがかかっている可能性がある場合は、メインルーチンかどこかで、このフラグを0にしておかないと、GPIO割り込みがかかるタイミングでなくても、GPIO割り込みがかかったように見えるので注意が必要。
微妙にクセがある。
カウンタの値を設定することができない(カウンタ値はDBxxxDR0レジスタだが、これはRead-Only)。つまり初期値を直接設定することができない。したがって、指定した時間(カウント値)だけたったらTerminalCountで割り込みをかける、という使い方ができない。
また、カウンタの値を読むためには、Counter8_bReadCounter()等を使うことになるが、これはいったんカウンタを止めて値を読んでまだ動かす、という動作をする。(APIのこ関数のSideEffectのところに書いてある)直接DBxxxDR0を読むのではダメ(常に0が返る)ようだ。つまりカウンタの値を読みながら、ある値だけ変化するまでPollingする、という使い方は、特にPollingの頻度が高いと、正確な計時ができないことになる。
データシートを熟読してみたが、カウンタが止まっているときは、Period(周期)レジスタに書き込むと、そのままカウンタ値にも書き込まれるようだ。ちなみにカウンタが動作中は、カウンタ値が0になったときに、Periodレジスタの値がはじめてカウンタにロードされる。
したがって、
昔なんかのときにつくったプログラムを使い回していたのだけど、データが送れない、という現象に遭遇して、改めて設定をしらべてみると、フロー制御を有効にしていたのが原因のようだ。具体的には、termiosのc_cflagで、CRTSCTSビットを立てているとフロー制御が有効になってしまうので、これを立てないようにしておく。
LEDのK側をGND、A側をAnalogInに接続して光センサとして使うと、当然ながらA側の負荷容量で大きく充電時間が変わる。たとえばオシロのプローブをつけたときとつけていないときではぜんぜん違う。AnglogInをPGAにつないで、PGAの出力をオシロで観測すると、その違いがよくわかる。現実的には、無負荷時には充電時間が短いので、リセット(A=GNDで駆動)後、1ms後ぐらいに電圧を読む必要があるが、ADCINC12ではぜんぜん間に合わない。そこで、ほぼすぐに値が得られるSAR6を使うと、ADCのタイミングさえうまくあわせれば大丈夫そうだ。(ADCのタイミングは、原始的な方法だが、空いているピンにトリガーを立てるのが簡便か)
SDCard_Select(SDCard_ENABLE)後の状態だと、SDカードのCSbがアサートされているので、SDカードでの消費電流が比較的大きいが、SDCard_Select(SDCard_DISABLE)すると、SDカードのCSbがネゲートされるので、SDカードの消費電流がぐっと小さく(カードによるが-30mA程度)なる。
ドラッグでできるみたいだ。知らんかった・・・
#pragma abs_address で絶対アドレスを指定(そのアドレスはflashsecurity.txtに書いてある)して、Constの変数を配置しておく。
http://edycube.blog2.fc2.com/blog-entry-327.html
→(10/04/05追記)これはImageCraft C用の書き方の模様。HITECH-Cでの書き方は不明のまま。困った。
PSoCのDeltaSigmaADC(DELSIG8)ではまる。以前自分ではまったFAQであった。
http://akita11.jp/diary/archives/2008/07/psocadc.html
DELSIG8のモジュールとして設定するクロックはTimerにいくだけで、アナログブロックへのクロックは、手動で(しかもモジュールとして設定したクロックと同一に)設定しなければならない。ちなみにアナログのクロックソースをTimer16のTerminalCountにしたいときなどは、そのTimer16がおかれているディジタルブロック(のTerminalCount出力がついている側)に接続すればよい。
いまさらながら、再現性の高いコツをつかんだような気がする。
位置あわせは厳密に。適量の手芸用ボンドで固定するとよい。フラックスはつけすぎない。QFNパッケージの端子側に半田が乗るように、基板を斜めにして半田づけするとやりやすい。
どうもGetRxBytesAvailable()でバッファ中のデータのバイト数を取得しようとすると、ときどきハングする(この関数から戻ってこない)ようだ。こまったな。バッファが空になるまで空読みしようと思っていたんだけど、そういうことができないじゃないか。回数決めウチで空読みするか。
「コネクタープライヤー」という工具で、芯線と被覆を同時に圧着できるようだ。
http://www.engineer.jp/product/pa08_10_15/pa08_10_15_16.html
ただしその分、芯線・被覆のサイズ(径)に制約が強い。
VDD=3.3Vのとき、ADC8の入力が2.7Vぐらいを超えると、どうも帰ってくる値がおかしくなる。(大きくバタついたり0xffにはりついたり)
ADC8のデータシートでは、ADC8_FULLRANGEを指定してStart()すれば0〜VDDの範囲を入力できると書いてあるが、CY8C21123のデータシートのDC特性をみてみると、アナログブロックのアンプのコモンモード電圧が0〜(VDD-1V)と書いてある。これが原因じゃないか。つまり、CY8C21123の仕様上、入力電圧は0〜(VDD-1V)に制限される、ということか。ADC8のデータシートの書き方が紛らわしい。
PC側のドライバのバッファの構造がよくわからない。
PCへの転送を停止させて、バッファ内のデータを全部読み出したあと(空になるのを確認してから)、1バイトだけPCへ送らせるようにすると、なぜかときどき300バイトぐらいバッファに残っているときがある(空のときもある)。ただしそのかたまりを読み出したあとで、もう1回、同じように1バイトだけPCへ送らせると、所望の1バイトが受信される。PC側のドライバのバッファの受信にレイテンシがあるんだろうか。それともダブルバッファになっているのか?とりあえず一連の動作(読み切り→1バイト送信させて読み出す)を数回ダミーで繰り返したあとで、改めて1回やるようにすれば、問題なさそう。
macyu氏に導かれて、マルチスレッドをマスターしようと目論む。
http://codezine.jp/article/detail/135
スレッドタイマを試してみたが、やはり50msぐらいが下限のようだ。
そこで、バックグラウンドの別スレッドで無限ループをまわし、
処理のあいまにSystem.Threading.Thread.Sleep(20);(20ms間sleepする)のようにしてみると、だいたいその時間ぐらいの周期で処理がまわってくる。20msぐらいまではイケそうな雰囲気。Sleep時間を10msにすると、平均で15msぐらい、というところか。(もちろんマルチタスクOSなので、他のアプリの実行状況などに依存する)→Sleepをいれずに無限ループをまわしても、親スレッドの反応が悪くなるわけでもなく、CPU利用率もほとんど変わらないようだ。(10/01/28追記)
Xilinx ISEでBehavioralSimulationをしようとすると、クロックの設定のところを終わるところで、ISEごと落ちてしまう。よくソースをみてみたら、moduleのポート宣言のところに、ミスでクロック信号がダブっていた。こういうエラーになるのか・・・
FT2232Hのデータ転送速度は、PC側のD2XXドライバのバッファのサイズと、PC側の読み書きの周期によって決まることになる。試しに以下の条件で実験。
WR#パルスの周期が122kHz程度で、63488バイトが上限のようだ。つまりこれがPC側の受信バッファのサイズ、ということか。
PC側のタイマ周期を60ms(16Hz)、バッファサイズを60000バイトとすれば、60000×16=1Mbyte/sというところ。
大きすぎても小さすぎてもだめ。
http://www.picfun.com/midi2c02.html
トラ技2010.2でみつけたFTDIのFT2232H。FIFOモードもあって、APIも、CypressのEZ-USBよりわかりやすそうに見える。実測で20MB/s程度は出る模様。
http://www.hdl.co.jp/USB-101/index.html
http://www.ftdichip.com/Drivers/D2XX.htm
緑色の感度が微妙だったので、緑として502nm(青緑), 525nm, 575nm(黄緑)を使ってみるが、たいして変わらない。また、特に青の受光感度が悪い。赤と緑だけだったら余裕そうだ。(ただし緑をあてても赤にも光電流はかなり流れる)
TektronixのDSOでFFTをかけると、周波数成分の強度がdBで表示される。基準がわからないので、振幅を変えた正弦波を与えてみると、0dB=振幅=1.4V=実効値1.0V、-10dB=振幅0.45V=実効値0.32V、となった。つまり、実効値Vrmsに対して、20log_10(Vrms)、ということのようだ。
吸い込みが+、吐き出しが−、という定義。
http://www.necel.com/faq/ja/f_spec1.html
RGB3色LEDに、RGBそれぞれの色のLEDの光をあてて、光電流で充電させてみる。目論見では、RはRにだけ選択的に光電流が流れるのかと思ったのが、さすがにそこまで波長弁別性はよくないようだ。緑や青をあてても、ほとんど同じように充電されてしまう。さすがに色センサ化は困難か。
ピン数が多いパッケージのPSoCでも、デジタルI/Oはその分増えているが、アナログ入力は、本当にACBの入力に使えるのはP0の8本だけ。もうちょっと多くしてほしいなあ。たとえば24本とか。
AlteraのFPGAのI/Oピンは、いろいろと融通が利かないようだ。
・1本ごとにプルアップのON/OFFは指定できない(全体でON/OFFの指定だけ)
・しかもクロック入力のようにプルアップ抵抗が備わっていないI/Oピンに対しても↑の指定が効くので、「そのピンにはプルアップはできません」というError (Warningではない)が出てしまう。つまりクロックピンを明示的に指定している場合は、プルアップ抵抗そのものが使えない
・プルダウン抵抗はそもそも指定できない
ちなみにXilinxのやつは、いずれもできる。
小型のなんちゃって定点カメラをつくって、やってみた。
http://akita11.jp/diary/archives/2009/11/post_917.html
ちょっと思い立ってDSPを使ってみようと思い、学科所有のAnalogDevicesのSHARCボードとVisualDSP++を使ってみる。が、VisualDSP++が、ライセンスがとれないと、どうも起動できない。へんなエラーだな、と思ったら、RemoteDesktop接続経由ではVisualDSP++を起動できないらしい。まあボードをつないで使うんだから、当たり前といえば当たり前だけど、そういう仕様なのか。
たまにうまくいかない現象に遭遇。しかも再現性が低い。電源周りを疑ってみたが、結論として、PCからPickit2までのUSBケーブルが長すぎたのか、USBハブを通していたのが原因で、書き込み時のPickit2からの供給電源電圧が下がっていたのが原因の模様。USBケーブルを短く、かつUSBハブをはさまないようにしたら、OKになった。
PICへICSPでプログラムを書き込むとき、Pickit2などのライタから電源を供給することができるが、電流容量は100mA程度。ボードのほうに電源供給されている場合は、Pickit2では自動的にその電源を利用するが、4.5V以下の電源ではブロックイレースができない。つまり3.3Vで動作するPICに、そのボードの電源を使ってICSPはできない、ということ。100mAなんてすぐに超えてしまうので、書き込み時だけ、PICをボードの電源から切り離せるようにしておくのが無難、ということか。めんどいな。
参考データ。
http://slashdot.jp/~espy/journal/416700
これまでややサボりぎみだったが、通信相手の電源を動的に切ったりすると、受信(RX)ラインが0V=Lに落ちるため、PSoCにとっては、フレーミングエラー(RX=Lなのでスタートビットと判断して受信開始するも、ストップビットがない、ように見える)になるので、ちゃんとエラー解除をしないといけない。エラー解除は、一番簡単なのは、UARTモジュールをStopしてStartすること。
http://projectmcx.cocolog-nifty.com/blog/2007/01/psoc_f00e.html
PSoCのE2PROMの備忘録。
http://dr.matrix.jp/psoc.html#a5
ポイントは、flashsecurity.txtの当該ブロックをなおす(Uにする)ことと、1ブロック=64バイトで、flashsecurity.txtのWやUの1文字は1ブロック(64バイト)、ということ。つまりDeviceEditorのほうで設定する開始block番号の64倍が、flashsecurity.txtでUにするべきアドレス、となる。
回路をつくっていて、何かの拍子に、DesignのTreeの中にあったファイル(回路/module)が、?になったりすることがある。
今回の原因は、*.vのmoduleのところに、何かの拍子に1文字入ってtmoduleになっていた。*.vの中にmoduleで定義してある名前がみあたらないので、DesignのTreeの中で?に変わる、というからくり。素直にSyntax Errorといってくれれば気づきやすいのに。
PastelMagicのBBSで質問してみたところ、回答をいただいた。
http://www.pastelmagic.com/psocbbs/index.cgi?m=read&bnum=1731&num=1733
どうも、「仕様」らしい。
FAT16でファイル数を気にして使うか、FAT32を避けるのが現実的か。
FAT16の仕様では、ルートディレクトリにおけるファイル数は512まで。またPSoCのSDCardモジュールは、ルートディレクトリにあるファイルしか扱えない。
つまり、PSoCでFAT16のSDカードに書き込めるファイル数の上限は512ということになる。
しかし512個目を超えても、fopenはできるようだ。しかし書き込もうとすると、FATが壊れるようで、PCからは読めなくなる。SDCardInitの戻り値も、ファイルシステム種類を示す上位4ビットが0になってしまう。
てっきり上限に達したら開けない(fopenでエラーが返る)のかと思っていたら、FATを壊してしまうのか・・・おそろしい。
ちなみになぜかFAT32で(Winで)フォーマットしたSDカードだと、途中128個目ぐらいで、同様にFATが壊れる。なんでだろう?
あまりないかもしれないが、EagleとPCBEで設計したデータとマージする方法について。Eagleはガーバーインができずないので、Eagle上でマージはできない。PCBEはガーバーインができるが、Eagleは正方形・円以外のアパーチャを使うので、そのままでは読み込めない。GCONVを使うテはあるが、いまいちうまくいかない。
そこで、以下の手順を踏んでみる。
Spartan3には、DCMというクロック生成回路が入っている(Virtexや他社のFPGAも、だいたい入っている)。
DLLでクロックの逓倍ができるわけで、その設定Wizardが、欲しいクロック周波数を入れると逓倍比と分周比を求めてくれるんだけど、非整数の値を求めて、あたかもそれで動くように表示される。
もちろんそんなわけはなくて、逓倍比と分周比は整数しかできないわけだけど、まぎわしい。
ところで、欲しい周波数に最も近い周波数を得るための逓倍比と分周比を求めるのは、数学的には、ある実数を、最もよく近似する有理数n/m(ただしn, mはN以下の整数)を求める問題、といいかえられるわけだけど、それはどうやって解くのが一番いいんだろう。とりあえず総当たりで求めてみたが、もっと良い方法がある予感。
振幅が1V(=2Vp-p)の正弦波をオシロ(50Ω負荷)に与えてFFT解析すると、その周波数の成分の電力が10dBm、とでる。
振幅が1Vの正弦波の実効値は1/√2Vなので、50Ω負荷に対する電力PはP=V^2/R=0.01W=10mW。dBmは、1mWの倍率としての絶対値なので、これをdBm表記すれば10log(10mW/1mW)=10dBm、となる。
本格的にタップを立てる。太いビスのあたまのところに立てる。
・下穴は、旋盤やボール盤で。旋盤の方が中心を取りやすい。
・下穴をあけたあと、バリ取りをかねて、円錐形の刃で入り口を少し広げる
・タップは旋盤やボール盤で垂直に。
・まずは先(1番)or中(2番)タップで、最後は仕上げ(3番)で。
↓↓の、OFFのときの電圧が下がりきらない原因がわかった。モジュールの入力に与えている信号があって、そいつがHighレベルになっていた。そのため、電源がOFFになっても、入力保護ダイオード経由で電流が流れていたわけだ。
電源をOFFにするときには、モジュールに与える信号をすべてLowレベル(0V)にするようにしたら、電源電圧はほぼ0Vまで下がり、消費電流もほぼ0になった。
ハイサイドSWの、いわゆるON抵抗が意外と大きいので、実際にモジュールに供給される電圧に注意。必要に応じて、低抵抗のフォトリレー(SSR)を使うべき。
SleepTimerは、てっきりsleepモードに入って、一定時間たったら戻ってくるのかと思いこんでいたが、単なる思いこみ。
M8C_Sleepでsleepに入り、そこから戻るのに、SleepTimer割り込みを使う、ということ。
しかしSleepTimer_TickWait()とSleepTimer_SyncWait()の違い、特に後者が、いまいちよくわからん。
カメラなどのモジュールの電源の+側を、PNPトランジスタでON/OFFする回路をつくってみる。
ONは問題ないんだけど、OFFにしても、モジュール側の電源端子(PNPトランジスタのC側)の電圧が下がりきらない(例えば2Vくらい)。
こんな中途半端な電圧だと、リセットもかかるにかからず、困るんじゃないか?と思ったが、消費電流はほぼ0に落ちているようだ。
よく考えたら、PNPトランジスタのC-E間のOFF状態の抵抗R_CE(off)と、モジュールの負荷としての等価抵抗との分圧が、ここの+端子の電圧になるわけだが、R_CE(off)は非常に大きいので、少しでもモジュールに電流が流れると、ここの+端子の電圧はほぼ0Vまで落ちるはずなわけで、そうなっていないということは、モジュールには電源電流は流れていなくて、OFF状態のモジュールの負荷としての等価抵抗が非常に大きい、というわけだ。
むかしハマったのを忘れていた。
http://akita11.jp/diary/archives/2007/07/post_637.html
else ifをたくさんつけたり、ifの条件をいろいろORしたりすると、場合によって、リンク時あたりに、よくわからんエラーが出る(再現性あり)。Tempにあるtempなファイルの中にあるエラー、と表示されるだけで、そのtempなファイルがみあたらないので、原因がわからない。
elseやORなどを減らすと、問題なくコンパイルがとおる。
なんじゃこりゃ?
割り込み処理中に、(念のためDisableIntしたうえで)もう1バイト受信すると、また割り込みフラグがたってしまうようだ。そのため、割り込み処理が終わると、また割り込みがかかってしまう。
レジスタレベルでこのフラグをクリア(DCB??を指定しないといけないので、Place依存なのでまりやりたくない)するか、割り込み処理中には1バイトしか受信しない(本来はこうするべき)ようにプログラムを書く、というところか。
1バイト単位での受信割り込みに、いまいち恐怖心というか避けたい気分があったのだけど、冷静に考えてみれば、あまりややこしい話ではないようだ。
http://web.sfc.keio.ac.jp/~shokai/archives/2008/03/psoc-cy8c2946-uart-recv-int.html
http://projectmcx.cocolog-nifty.com/blog/2007/01/psoc_f00e.html
要は、本来の受信割り込みは1バイト受信した時点で起こるが、標準で生成されるCmdBuffer関係の処理がUART_int.asmに書かれているので、その前に、自分の割り込み処理ルーチンへljmpさせてしまえばOK、ということになる。
なるほど。
sleepに入ると、pull-upはoffになる(=電圧が0Vになる)ようだ。つまりpull-upの上の電源がoffになる、ということか。
PSoCの外部IO割り込みのenableは、PRTxIEの当該ビットを1にして、かつ、PRTxIC1/0の当該ビットで00(disable)/01(立ち下がり)/10(立ち上がり)/11(両エッジ)を設定する。PRTxIEの設定を忘れがちなので注意。
備忘録。アクリル板だと意外と簡単に開く。
http://homepage3.nifty.com/yamaca/jisaku2/tap.htm
下穴は、仕上がり穴径-1mm程度、か。最初にボール盤を使って垂直にタップをあてるのがポイント。
オーディオ用語。シャーという音。高周波成分なので、LPFである程度カットできる。メインアンプ前が効果的。
http://www.computar.jp/modules/computar/index.php?page=cat&id=23
このあたりのボードレンズのマウントを自作してみようと考える。
マウントはM13P1.0、つまりネジ径13mmでネジのピッチが1.0mm。けっこう特殊なサイズのようだ。
汎用品でのナットはなかなかみつからず、
http://store.shopping.yahoo.co.jp/kokua/yamawatnp13100b.html
このあたりのタップを使ってみようと考える。
タップの「先」「中」「上」というのは、用途に応じた先端の形状らしい。
http://www.recoilj.com/recoil-tap.html
いろいろ関連技術がまとまっているので備忘録。いろいろある。
http://www.tsukuba-tech.ac.jp/info/kenkyu/kaken/disp2.html
作ってみた。コネクタ部分は、↓と同じ回路。とりあえずテスト的な測定ならば十分そう。
同期式シリアル通信であるSPI送受信回路を、HDLで書いてみるが、Behaviorシミュレーションでは動くのに、実機だとどうも挙動があやしい。
always @(negedge CK or posedge RST) begin ... case (rcnt) 8 : DBi[9] <= MISO; 9 : DBi[8] <= MISO; ...
こんな感じで、何ビット目かのカウンタ(rcnt)の値に応じて、結果レジスタの各ビットに受信データを書き込んでいるわけだが、書いているが、SPIの仕様上、送信と受信はCKのエッジが逆なので、送信側と受信側で、posedgeとnegedgeを使い分ける(か、2倍の周波数のクロックを使う)しかないわけだが、どうもこいつがマズいっぽい。論理合成後のRTLレベル回路図を見ると、各ビットのフリップフロップの前の組み合わせ論理回路がえらいことになっている(そりゃそうだ)。
そこで、同じようなものだが、1ビットずつシフトするように書き直してみた。
always @(negedge CK or posedge RST) begin ... else begin DBi[9:0] <= {DBi[8:0], MISO}; end
クロックの逆エッジを使っているのは同じなので、ダメかなあ、と思ったら、意外とあっさり動くようだ。
しかしこういう両エッジを使わざるを得ない回路の場合は、どうやって書くのがスマートというか流儀なんだろうか。やっぱ2倍クロックで立ち上がりのみ、なのかなあ。
簡易測定用に、先端がつまみやすい形状のプローブっぽいものを作ってみようかと思い立った。プローブ校正用のトリマ付近の等価回路
http://techon.nikkeibp.co.jp/article/NEWS/20070905/138795/
忘れないうちにまとめてみた。
http://akita11.jp/plan/pcbeguide/
けっこう難しい。近いうちに、いろいろまとめる予定。
前々から微妙に気になっていた、VLSI Solutions(http://www.vlsi.fi/)のMP3デコーダVS1011eを試してみる。
秋月でも売っている。http://akizukidenshi.com/catalog/g/gI-01484/
本来は、MP3形式(など)のバイナリデータをSCI経由で流し込むと、デコードして再生してくれる、というものなのだが、ファームウエアを持たせることができて、SDカードをつないでそこの中のMP3ファイルを再生する、みたいな機能もできる。
アプリケーションノートにある、Standalone Playerをみてみると、こういうプログラムを起動時にSCI経由で流し込めばOK、というのが載っているので、そのまま使ってみる。ファームウエアといっても5KB程度なので、制御用のマイコンのプログラム自体に入れてしまうこともできる。
で、ちょっと苦労しながら試してみた備忘録。(少し参考:http://www.picfun.com/PIC24F/AP/app24F08.html)
しかし、どうもこいつのデータシートは、性にあわないのか、非常に理解しにくかった。レジスタ名とフラグ名が、似ていてまぎらわしい、のが理由なんだろうか。
備忘録。VDDを分圧してVrefとして与えるものしかない。
つまり電源電圧が変動すると、Vrefも、それに比例して変動するということ。
電池駆動しての絶対電圧の比較には向かない。3端子regなどで電源を安定化するか、ADCを使うか。
PSoC Designer5.0で、WorkspaceとProjectの関係が、ごちゃごちゃしてきたので、備忘録。
http://doggie.blog.so-net.ne.jp/2007-03-17
JP1のジャンパーピンを下側へ移動させるだけ。
PSoCのI/Oピンの駆動モードを例えばPull-downにすると、PRTxDRで、そのピンのビットを0にしないと、Pull-downは有効にならない。
で、そのピンでSWなんかをつないでRising-Edge割り込みをかけたいとすると、そのピンが1になったときに割り込みがかかるわけだが、それにあわせてPRTxDRのビットが1になる。これを、再び0にしないとPull-downが有効にならないわけだが、その割り込み処理ルーチン内でPRTxDRのビットを0にしても、SWを押している間は、そのピンが1なので、PRTxDRのビットも、0にできない。つまりSWを離したあと、改めてPRTxDRのビットを0にしないといけない。(ただし当然ながら、そのSWを離したことは、PRTxDRのビットを0にできないので、Falling-edge割り込みでは検出できない)
PRTxDRのビットを適宜0にする方法は、例えばmainルーチン内のwhileループ内で常時やタイマ割り込みで定期的にPRTxDRのビットを0にする、といったところ。
http://www.aki-den.jp/kit_manual/start.html
マトリクスLEDを、センサとして使う、という話。元ネタはいろいろあって、例えばhttp://elm-chan.org/junk/leddet/report.html など。
(以下、行:アノード側、列:カソード側と定義)
以下の手順。
ふと思い立って、リセット動作を、行・列ともに"0"にしてみて、蓄積中の当該列を"0"にしてみる。
蓄積にしたがって電位は上がっていくが、どうもこのほうが動作の安定度がよいようだ。
うまくやると、CもRもつけなくても大丈夫。
レーザーポインタぐらいの明るさだったら問題ないようだ。ペンライトぐらいの明かりで、どれぐらい動作するかは要チェック。
ややノイズにシビアな信号を扱う回路で、アナログと高速で動くディジタル(FPGA)が混載している回路のノイズを退治する。
いろいろトライして、結果として最も効果があったのが、アナログ回路(アンプ)に対するパスコン(0.1uF程度)。最初は、ディジタル回路の方にパスコンをつけて、そこが発する電源系に乗るノイズを退治しようとしていたが、なかなかうまくいかない。そこで、そこから出るのはしょうがない、と割り切ったら、それなりに効果があった。
たとえばFDKのCR2032で、220mAh@2.0V程度らしい。思ったより大きい。
http://www.fdk.co.jp/battery/lithium/cs03.html
↓の結果。併用すると、かなりよくなった。
最後は、ADCに入ってくる信号にのるクロック由来のノイズ。
こればっかりは、アナログ系のPCB配線をしっかりやるしかない。
CPLD(XC2C256)で、シリアルのADCをつついてみるが、どうも誤作動する。
具体的には、CPLDから与えているクロックの立下りでADCから出てくるデータが変化するはずなのだが、毎立下り以外でもデータが変化しているっぽい。オーバーシュートか。
ADCの入力ピンの規格だと、Lは0.8V以下、Hは2V以上となっているが、確かに0.8Vに近いオーバーシュートが出ている。
考えられる対策:
ついでに、コンデンサマイクで拾った音をライン出力まで持っていく増幅回路の備忘録。
http://cba.sakura.ne.jp/sub04/jisaku19.htm
PCで、ちょろっと音を取り込んで、ちょろっと加工して出力したくて、調べてみると、Pdというやつがある。
http://d.hatena.ne.jp/octech/searchdiary?word=*[PD]
ただ、マイクは、どうもモノラルしかできないようだ。
http://blog.atamanikita.com/?eid=817204
ちょっと気が向いて、DirectSoundのプログラムを書いてみたいと思ってみる。ちょっと調べた範囲の備忘録。
http://quickprogram.blogspot.com/2008/07/managed-directx.html
http://www.tnksoft.com/reading/classgame/engine/03/030.php
http://hikari-hinomoto.hp.infoseek.co.jp/
http://www.clks.jp/csg/dx001.html (環境構築とか)
http://www.geocities.jp/chako_ratta/micon/psoc_rectifier.html
久しぶりにDCモータの定速回転を半日で仕上げる。エンコーダの出力のカウントがキモなわけだが、けっこう周波数が低いので、パルスがHになる時間をカウントすることにする。PSoCでやる方策をいろいろ考えてみたが、Counterで基準クロックをカウントさせ、そのEnableにエンコーダのパルスをあたえ、そのエンコーダの立下りで割り込みをかけてCounterの値の差分をとる(Counterの値をリセットする、という方法がわからない)、というのが、現実的のような気がする。
↓と書いたものの、動作が微妙にあやしいので、Post-fit Simulationをやってみると、予想以上にSetup-timeが短い。こりゃ動作が微妙なはずだ。
というわけで、全体を同期のステートマシンになるようにVerilogの記述をなおしてみるが、根本的には解決できず。
冷静に考えたら、クロック周波数が48MHzなのに、tpdが10nsのCPLDを使っているのが、そもそも無茶なようだ。もう少しtpdが短いCPLDを使ってみることにする。
比較的高速に動く回路をXilinxのCPLDに焼いてみるが、微妙に動かないところがある。
具体的には、ビット列のうち、特定のビットだけ、値が1に張り付く。
どうも遅延っぽいなあ、と思って、fittingのpropertyにあるOptimizatingをSpeed優先にしてみたら(デフォルトはSize優先)、あっさり動いた。
千石(http://www.sengoku.co.jp)で売っていて、よく使うんだけど、型番不明で、千石以外では入手ができなかったコネクタのメーカと型番を、やっと見つけた。
https://www.linkman.jp/user/shohin.php?p=57596
リンクマンという会社のZL2543シリーズ。
昔作ったやつを久しぶりに動かそうとしたら、どうもうまく動かない。
原因を探っていったら、基板の裏に通っているビニール線が、挿入実装部品の足のでっぱりに刺さっていて、運悪くショートしてしまっていたようだ。
USBでデータをもらいながらグラフを描画していると、どうも時々、エラーになる。
デバッガで原因をさぐってみると、どうもBeginTransferに失敗することがあるようだ。
原因をいろいろ考えてみたが、グラフの描画(とその準備の処理)に時間がかかる(ことがある)のが原因のような気がする。
グラフの描画の頻度を下げるしかなさそうだ。
PSoCのI2CHWのデータシートに載っているsampleに、どうもバグがあるような気がする。
WriteやReadの終了判定を
while(!I2C_RTC_bReadI2CStatus() & I2CHW_WR_COMPLETE);
とやっているのだが、&より!が優先されるので、
while(!(I2C_RTC_bReadI2CStatus() & I2CHW_WR_COMPLETE));
じゃないとマズい。
ちょっと多めのビニール線を半田付けしないといけないことがあり、買ったけどつかっていなかった半田槽を使ってみる。
棒はんだ(やになし、Sn60%)を細かく切って槽にいれ、設定温度を400℃ぐらいにして溶かす。その後、ビニール線を突っ込んで、少し待つと、だいたいきれいにできるようだ。
一度冷ますと、半田の表面に酸化膜っぽいのができるが、内側は大丈夫なので、再度溶かせば、また使える。
結局、送信が終わったあと(=受け側がデータを受け終わったあと)、受け側の送信端子(=PSoC側の受信端子)がHighになるようなので、送信が終わるまでUART_bReadTxStatus()をみて送信が終わるまでまち、その後、(必要であれば、その受信端子が1になるのをポーリングで待ってから)受信を開始するようにすると、うまくいくようだ。
どうもPSoCに限らず、UARTの受信エラーと、その対策が、いまいちよくわからない。
例えば受信端子をずーっと0にしてしまうと、フレーミングエラーが出るわけだが、
そのエラーフラグをクリアすれば、次からはまた普通に受信ができそうなものなんだけど、どうもうまくいかない。もっとシビアにタイミングを見てあげないといけないのかなあ。具体的には、受信端子のサンプリングのタイミングと、データ受信完了のタイミング。
5Vで動作するようにconfigしてあるPSoCを一度書き込んでしまうと、3.3V用に改造したMiniProgでは書き込みができないようだ。
ときどきコンパイル時に謎のエラーがでる。
HITECH-Cのフォーラムで質問してみたら、どうもServicePack2で
修正される問題、らしい。
Xilinx ISEで、Runをすると、その段階だけ実行される(ことがある)。例えばGenerate Programming FileのところをRunすると、SynthesisやImplementationは実行されない(ことがある)。Rerun allだと、最初から全実行。
作ったはずの回路ができず、これで1時間ほどつぶしてしまった。
教訓:コンパイルの過程に注目しよう。
ためしにPWM16をStartしなくしても、パルスが出てくる。
そんなはずはない。
もしかして、と思って、プロジェクト内のmain.cを見たら、ずいぶん前のプログラムだった。ということは、どこかで違うmain.cをひらいて、そいつを編集していたわけだorz
すごく簡単なプログラムを作ってみるが、どうもうまく動かない。
PWM16で、PWM16_WritePeriod()とPWM16_WritePulseWidthを設定してパルスの周波数を変えたいのに、InterconnectViewで設定している値から変更がきかない。なんじゃ?
ちなみにPWM16などのクロック信号は、電源3.3Vでは、グローバルバスに引き出せるのは12MHzまでらしい。見落としていた。
いろいろ検索して、2chに行き当たる。
結論として、(Tutorialにも書いてある)いままでのImagecraftコンパイラの書き方でも、Warningは出るが、使える、ということらしい。(本当は割り込みベクタのアドレスを記述するのがHITEC-C流らしいが、boot.asmをみないとブロックごとの割り込みベクタがわからないので、面倒といえば面倒)
実際使えたので、Warningは気にせずにこのまいくことにする。
新しいマシンに、PSoC Designer5.0をインストールしてみる。HITECH-C Liteを選んでいるんだが、
!E C:(Path名)\tools\InvalidCompilerLicense.txt(0): ...Operation terminated. Compiler License invalid or not accessible
と出てしまい、コンパイルができない。なんでだろう?
Googleで検索した範囲では、古いコンパイラの情報が残っている場合などに出ることがあるようだが、今回は更に入れたマシンなので、そんなことはないはず。
ためしに、45日評価版のライセンスに切り替ええても、やはり同様のエラー。
困った。
三端子レギュレータの出力電圧が、予定より0.5Vほど高くなる現象に遭遇。負荷はFPGAのI/O電源。
もしかして、と思ってデータシートを読み直してみると、出力電圧の項が、負荷電流が5mA以上、という条件で書いてある。
というわけで、適当な抵抗を負荷につないでみたら、無事本来の出力電圧になった。
スイッチングレギュレータで負荷の下限があるのは知っていたが、三端子のようなシリーズレギュレータでもあるんだね。
ふと思うところがあり、ちっこいWebサーバを攻めてみる。
http://www.olimex.com/dev/pic-mini-web.html
ここのTCPスタック(バージョンは最新ではない)を書き込んでみるが、どうもうまくいかない。1回だけうまくいったんだけど、それ以外は反応がない。リバースケーブルでつないでも、HUB経由でもだめ。IPパケットをのぞいてみると、どうもARPに反応していないっぽい。なんでだろう。まさかARPってICMP_SERVERをイネーブルにしないと反応しないんだろうか?そんなわけないよなあ。
BluetoothモジュールについているSMAコネクタを交換するため、コネクタをとりはずす。
思いのほかコネクタの熱容量が大きいのか、熱風ブロアではビクともしない。
そこで、サンハヤトのSMD取り外し半田を使ってみる。
http://www.sunhayato.co.jp/products/details.php?u=797&id=02043
→あっさりとれた。すげー。脱帽。
北川先生より情報。
http://zedgraph.org/wiki/index.php?title=Main_Page
PSoC Designer5.0を入れてみる。統合環境としては、なかなか使いやすいような気はする。
カメレオンUSB FX2
http://optimize.ath.cx/cusb_fx2/index.html
USB2.0経由で、高速にデータを送り続けるような用途に吉。
いろいろと備忘録。
PSoC Designer 5.0を入れてみる。Cコンパイラが、HI-TECH Cになっている。
機能制限版は無料、フル版は有償(アカデミックで$650程度のようだ)、とのことで、とりあえず無料版でいってみる。
http://ameblo.jp/2st-rider/entry-10091603285.html
ここによると、いままで使っていたImagecraftのCコンパイラより、この無償版の方がいいこともあるようだ。むーん。
アカデミック版を買うかなあ・・・マルチユーザライセンスだし。
JST(日本圧着端子製造)のコネクタ(ACHシリーズ)のコンタクトピンにケーブルを圧着しようとする。
http://www.jst-mfg.com/product/detail.php?series=9
が、あまりにも小さいので、断念して半田付け。JSTに問い合わせてみると、専用の手動圧着工具がある。10万円ぐらいするが、これは専用工具を使わないと無理だ・・・
ちなみに、昔買っていた、同じくJSTのSSRシリーズのコネクタは、ピンにワイヤを押し込んで固定する圧接、という方法で固定するが、こちらも、同じくJSTの専用工具があるようだ。しかし15万円ぐらいする。まあこちらは、それほどまではよく使うわけじゃないので、精密ドライバで押し込むか・・・
アナログブロックを全く使わないとき、GlobalResourceからAnalog PowerをOffにすると、2mAぐらい消費電流が減るようだ(CY8C29466の場合)
ちょっと手が空いたときに、実験や測定するときの、ちょっとした環境整備。
DC電源を何系統か使うとき、どの線がどの電源につながっているかわからなくなっちゃうことがあるので、色をつけてみる。あと、平行コードで線がバラけないように。
オシロのプローブで基板上のICの信号などを見ているとき、プローブだとつまみにくいところをつまみやすいようにクリップ(Sunhayatoの、本当は0.5mmピッチQFPの足もつまめるシロモノらしい)。やはり同じように色分け。あと反対側は、プローブでつまむように皮をむいただけだけど、もちろん半田メッキ。
いろんなリモコンの信号をみてみる。
リモコンの赤外線を受信したくなって、久しぶりにちゃんと使ってみる。
備忘録。ユニクロメッキのナットを基板に半田付けしたい場合(ってかなりレアだな・・・)に、けっこううまくいく方法を発見。
備忘録。PSoC Programmerの2種類の書き込み方法
しばらくまえにいじろうと思って、なかなかうまくいかなかったので、しばらく放置プレイぎみだった、Cypressの2.4GHz帯無線機つきPSoCの、PRoC (CYWUSB6953)
http://www.cypress.com/products/?fid=65&rpn=CYWUSB6953&ref=sch
久しぶりにひっぱりだす。いろいろリハビリ。
多点CSD(具体的にはとりあえず12点)で、ちょっと電極までの距離が長いやつのタッチ検出。デフォルトのパラメータだと、感度がいまいち(というか誤検出が多い)ので、CSDのDocumentの最後の方に載っているチューニングの方法に従って、チューニングしてみる。
ちなみにCSDモジュールのReferenceは、ASE11がおすすめ、と書いてあった。ScanSpeedはNormal, Resolutionは12bitに設定。
チューニングの手順の要点は以下の通り。
結果は以下の通り。
(12個のスイッチのうち、SW0, SW5, SW11の3個のみ記録。値はけっこうバタつくので、俺フィルタを通したあとの平均値。タッチの強さによっても値が変わるが、弱めにタッチ(ワーストケースに近い)にしてみる。
OFF | On | Diff | ||||||||
Rb | Cmod | SW0 | SW5 | SW11 | SW0 | SW5 | SW11 | SW0 | SW5 | SW11 |
2.2k | 10n | 650 | 950 | 1100 | 1800 | 2050 | 2500 | 1150 | 1100 | 1400 |
2.2k | 4.7n | 650 | 970 | 1100 | 1800 | 2000 | 2600 | 1150 | 1030 | 1500 |
2.2k | 39n | 660 | 970 | 1100 | 2100 | 2200 | 2700 | 1440 | 1230 | 1600 |
2.2k | 47n | 660 | 970 | 1100 | 2000 | 2100 | 2500 | 1340 | 1130 | 1400 |
4.7k | 10n | 1300 | 1900 | 2200 | 3900 | 3800 | 4000 | 2600 | 1900 | 1800 |
10k | 10n | 2400 | 3300 | 3700 | 4096 | 4096 | 4096 | 1696 | 796 | 396 |
4.7k | 39n | 1300 | 1900 | 2200 | 3500 | 3800 | 4000 | 2200 | 1900 | 1800 |
4.7k | 4.7n | 1300 | 1900 | 2200 | 3800 | 3900 | 4000 | 2500 | 2000 | 1800 |
3.3k | 10n | 930 | 1360 | 1600 | 3000 | 3500 | 3600 | 2070 | 2140 | 2000 |
3.3k | 39n | 960 | 1390 | 1620 | 2700 | 2800 | 3500 | 1740 | 1410 | 1880 |
3.3k | 4.7n | 920 | 1360 | 1600 | 3400 | 3000 | 3700 | 2480 | 1640 | 2100 |
この結果から、微妙なラインではあるが、Rb=3.3kΩ, Cmd=10nFを採用。
本来は、このカウント値とBaselineとの差がFingerThreshold以上になったら、ON、になるはずなのだが、FingerThresholdの値が5〜255しか設定できない。これはResolutionが8bitのとき用で、12bitのときとかは、換算しないといけないんだろうか。
そのあたりをさぐるのが面倒なので、カウント値-baselineであるCSD_waSnsDiff[]を順番にみて、その値が閾値以上(例えば700)であればON、と判定するようにした。
ちなみにCSDは、勝手にVC1〜VC3のクロック源・分周比を設定してしまうので、TX8などのクロック源を自分で分周したVC3にできないので、SysClk*2で、PC側のUARTのボーレートをそれにあわせるか、CSDでセンスしたあとに、レジスタを直接いじってVC3のクロック源・分周比を設定(OSC_CR3/OSC_CR4)などしてTX8_Start()して、TX8でデータを送る。送り終わったら、TX8_Stop()して、レジスタを戻しておくのを忘れずに。(ただしTX8_PutCharの関数から戻るのは、送信開始時なので、送信が終わるまで待ってからTX8_Stop()しないと、途中で送信が止まってしまう)
電極までちょっと長め(最大で1m弱)の線で引っ張るタッチセンサをCSDでつくってみる。
電極までの線を、電極につながる線とGNDが交互になっているフラットケーブルにしてみて、どれぐらいイケるか挑戦してみた。(未来日記)
場合によっては、ShieldElectrodeを使うようにして、このフラットケーブル内のGNDをShieldElectrode端子につないだほうがいいのかもしれないが、それは結果をみてから、にする。