PICでVDDの供給電圧を自己測定する

PICマイコンは電池で動かすことも多いのですが、電源電圧が低下したときに、誤動作が起きる前に警告できないかと思ってためしてみました。

使っていたのは12F1822、このデータシートを眺めても、VDD電圧を直接得る方法はなさそうなのですが、ADコンバーターの記述の中で内臓の基準電圧があることや、これを入力チャンネル選べることが分かりました。
これを使って、外付け部品は一切なしで、しかもIOピンも消費せずにVDDが測れそうな気がしたので実験してみました。

 //100分の1V単位で電圧を返す。
//VDDを基準としてFVRの2.048VをAD変換する。
//2.048:VDD = AD値:1023 より、VDD = 2.048*1023/AD値
unsigned short VDD_get(void){
ADCON0bits.GO_nDONE=1;
while(ADCON0bits.GO_nDONE==0);
return 209510 / ADRES;
}

int main(int argc, char** argv) {
OSCCON = 0b01011010 ; // 内部クロックは1MHzとする
FVRCON = 0b10000010 ; // FVR 2.048V
ADCON0 = 0b01111101 ; // ADCのチャンネルをFVRに設定
ADCON1 = 0b10000000 ; // ADCの基準電圧をVDDに、データは右詰め
  unsigned short v;
while(1){
v= VDD_get();
__delay_ms(500);
  }
}

このようにしたところ、無事VDDが測定できました。0.1V単位でテスターの値とよく一致します。ただ、定期的に0.1V程度低い値を出力することがあったのですが、複数回測定して平均すれば問題ない範囲だと。

MAX7219搭載のユニットで7セグLEDを制御

PICマイコンで7セグLEDを表示するには、かなりのIOピンを必要とする。なんとかならないかと思っていたら、MAX7219搭載でシリアル通信で8桁のLEDを表示できる部品を見つけた。300円程度で購入できたので早速試してみた。

電源のほかには、3つのIOが必要で、I2CよりSPIに近いが、一方的に2バイト送り付けるだけなので、デジタルIOで送信する関数を使ったほうがよさそう。16F18325で試してみた。

/*
* 13 RA0 DIN 送信データ
* 12 RA1 CS 開始フラグ。Lowでデータ送信開始
* 11 RA2 CLK クロック供給
*/
void max_write(unsigned char addr,unsigned char data){
    int i;
    const unsigned char BitMask = 0b10000000;
    RA1 = 0;//CSをLowにして受信待機させる。
    for(i=0;i<8;i++){
        RA2 = 0;//クロックをLowに
        RA0 = (addr&BitMask)!=0;
        addr <<= 1;
        RA2=1; //クロックをHighに
    }
    for(i=0;i<8;i++){
        RA2=0;
        RA0=(data&BitMask)!=0;
        data <<=1;
        RA2=1;
    } 
    RA1=1;
    RA2=0;
}

この関数にアドレスとデータをパラメーターにして呼び出すと表示するはずが、なかなか動かなくてかなり苦戦した。
単純なミスで、初期化をきっちりしていなかったのが原因。mainで以下のようにすると無事動作した。

unsigned char i,j;

max_write(0x0C,0x01);//nomal oparation
max_write(0x09,0x00);//No Decode
max_write(0x0A,0x07);//LED輝度
max_write(0x0B,0x07);//ScanLimit
for(i=1;i<9;i++){
    max_write(i,0);
}

特に1つ目と4つ目が肝心、ShutDownモードになっていると全く動かない。Display
Testをすると、ShutDownが解除されそうな記述を見たけれど、そんなことはなかった。
ScanLimitを8桁全部にしておかないと、いくらデータを送っても反映されない。

できてしまえば、あとは非常に楽。数字だけなら、Decodeモードを使ったほうがいい。

PIC16F18325を使ってみた

DCモーターとRCサーボをコントロールするために、PIC16F1503を試してマイコンの勉強をしてみたのだが、ある程度なれたので別の石もと買ってみたのが16F18325。DIPの14pinというのが、ブレッドボードですぐに試せるのでありがたい。この石、同じ16Fシリーズでも1503とは全くの別物。メモリはでかいし、内臓オシレーターで32MHz駆動、タイマ等の機能がグレードアップしている。多機能な分、MPLAB XのプラグインMCCをうまく使う必要がある。

嬉しい発見があった。CLCを使うことで、意外と扱いが難しいRCサーボを内蔵PWMを使い、200~550程度の約350段階でデューティを制御できた。方法は、拡張されたタイマ0とタイマ2,CLCを使う。

まず、16MHzで駆動する。タイマ0は8ビットモードとし1:512のプリスケーラー、20480usでオーバーフローする設定にする。タイマ2は1:64のプリスケーラー、PR2の値はタイマ0と合わせる。すると、プリスケーラーに8倍の差があるので、同時スタートさせると、タイマ0が1回OFするときに、タイマ2は8回OFする。このタイマ2を発信源にPWMを動かす。

CLCで入力にTimer0overflowを選ぶと、overflowのタイミングでHighとなり、次のカウントでLowとなる。今回1:512のPSを設定しているので、128usHighが続きその後Lowとなる。

一方Timer2matchも同様だが、こちらは1:64のPSなので、High時間は16us。普通のSRラッチでも同時発生すれば必ずTimer0が勝つ。

 

MCCのデザイナを使い、CLCにT0overflowとT2matchを入力源として、図のようにする。

次に、このCLC1の出力とPWMの出力をCLC2でANDとれば出来上がり。

CLC2の出力は、PWM5を一回出力したら7回休み。20480us秒の最初2560us秒だけがduty変更の対象となる。RCサーボはおおむね800us~2200usが操作範囲だから、dutyは200~550が有効範囲となる。

 

 

 

このロジアナの表示は、D0がCLC0の出力、D1が、PWM5の出力、D2が最終の出力。これで割り込みを使わずハードウェア制御でRCサーボを滑らかにコントロール可能。ただし、CLCの数-1台までに限る。

ちなみに、eepromに書き込もうと思ったら、MCC3.36が吐き出すコードでは、ダメだったので注意。

さらに、simulatorのロジアナではCLCはうまく表示されないので、これも要注意。

PICマイコンで赤外線リモコンを受信する。

秋月電子で、赤外線リモコンが\300であった。面白そうなので、PICマイコンで受信するプログラムを書いたが、意外と苦戦したので、備忘録として書いておこう。

卓球の練習マシンを作っていたが、上ローラー、下ローラー、発射角度、発射周期、首振りなど調整項目が多く、アナログボリュームだと配線が大変だし、なによりマイコンのアナログ入力のピン数が増える。赤外線リモコンが使えれば、入力はデジタル×1で済むし、パラメーターを記録しておける。

で、使用したPICは16F1503 14pinDIPパッケージ。PWMが4つあり、モーター制御に向いている。ただ、DCモーターとラジコンサーボでは、PWM周期が違いすぎて両立はできない。よって、サーボはタイマ割り込みを使うこととする。

上記のことから、赤外線の受信には16F1503を内蔵オシレーターでの最高周波数16MHzで使用、タイマ1のゲート機能を使うこととする。赤外線受信モジュールは、常時Highで受信するとLowと逆転するが、かえって都合がいい。Highの部分だけを見れば受信可能だ。

リーダーが4500us、0が560us、1が1600us、リピートが2300usということで、16ビットタイマの上位8ビットのみを使いカウントする。

//リモコン受信データ
unsigned char IRBUFF[4];
unsigned char read_state=0;
unsigned char ir_repeat;

void interrupt isr(void){
    unsigned static char byte_pos;
    unsigned static char bit_pos;
    unsigned static char skip=0;
    unsigned char cnt;

    if (TMR1IF){            //タイマ1がオーバーフローした場合。
        read_state = 0;     //読み取り状態をリセットする。
        ir_repeat = 0;
        skip = 1;           // タイマがオーバーフローしたら、そのときのパルスは無効。
        TMR1IF = 0;
    }
    if (TMR1GIF){
        cnt = TMR1H;    //パルス High時間を取得 2us/count(L) 512us/count(H)
        TMR1L = 200;    //タイマの値を初期化。0.5ms程度のパルスでカウントできるよう下駄はかせ
        TMR1H = 0;
        if (skip) skip = 0;
        else switch (read_state){
            case 0:     //ヘッダ待ちモード
                if(7<cnt && 11>cnt){  //3.8ms~4.9ms ならヘッダ
                    IRBUFF[0]=IRBUFF[1]=IRBUFF[2]=IRBUFF[3]=0;
                    read_state = 1;
                    bit_pos = 0;
                    byte_pos = 0;
                    ir_repeat = 0;
                }
                break;
            case 1:     //ヘッダ完了。データ待ちモード
                if(1 > cnt || 4 < cnt){
                    read_state = 0;
                }else{
                    IRBUFF[byte_pos] |= (cnt > 2) << bit_pos++;
                    if (bit_pos==8){ //8bit読んだら、次のバイトへ
                        byte_pos++;
                        bit_pos = 0;
                    };
                    if (byte_pos == 4){ //4byte読んだら終了、次のパルスは無視
                        skip = 1;
                        read_state = 2;
                    }
                }
                break;
            case 2:     //読み込み完了。リピート待ち。
                 if (6 > cnt && cnt > 3){
                    skip=1;
                    ir_repeat = 1;
                }else ir_repeat = 0;
            break;
        }
        TMR1GIF = 0;    //割り込みフラグを解除して
        T1GGO_nDONE = 1;//ゲート待機モードに
    }

}

 

シースルーHDD2

シースルーHDDが成功したので、今度は最初から動かすつもりでシースルーHDDの製作に挑戦しました。

R0010012動いているところを見るためには外付けにする必要があります。で、IDE接続の2.5インチHDDを使います。これならUSBバスパワーで駆動でき、USB変換アダプタも安い。ノートPCのHDDを交換した時にとっておいた古いHDDを分解します。

プラッタには絶対に触らないようにします。

万が一手の油がつけば再起不能は間違いないでしょう。

R0010018蓋を加工します。

アームの軸受け部分など、ねじ穴はすべて残しそれ以外の部分を大きく切り抜きます。写真は加工後の蓋と切り抜きに使った工具(ハンドニブラー)。

ハンドニブラーは、穴から刃を差し入れ、一度に数ミリずつ切り進む工具で、鉄板なら厚さ1mm程度まで大丈夫です。なにかと便利な工具ですね。

R0010021 切り抜いた穴より一回り大きく切ったアクリル板を取り付けます。

取り付けには、気密性を保つために、弾力性がある接着剤、セメダイン スーパーXを使用しました。

蓋の取り付け時にできるだけ埃が入らないように注意します。

R0010027完成したシースルーHDD。

HDD外付けBOX(約1000円)を購入し、PCに接続して動作確認をしました。

しかし、HDDほど高精度になると、プラッタが回転しているのがほとんどわかりません。プラッタ取り付け部のビス部分をみるとはじめて回転しているのがわかる程度で面白くありません。

フォーマットからディスクチェックをすべてクリア。念のため、巨大なファイルを読み書きするプログラムを作り、1晩中ディスク全域を使い読み書きのチェックを行いましたが、異常なし。

今度は、シークをみるために、激しくランダムアクセスを繰り返すプログラムを作りテスト。アームがすさまじい速度で往復するのが良く見えました。

無事、完全に動作するシースルーHDDの完成!

※真似するときは、くれぐれも自己責任でお願いします。

シースルーHDD

ファイルサーバーに接続していたUSB-HDDが不調になりました、なんども読み込みを試みて、エラーで終了する症状です。なかには読めるファイルのあるのですが・・・

どうせ故障するなら、一度HDDの動いているところを見てみたかったので、こいつを分解して透明の窓をつけてみることにしました。もともと不良のHDDだったので、再起不能になっても惜しくないし、うまくいけばヘッドがシークしているところがみれるかも、という思惑です。

かなり無茶な試みなので、決してまねをしないように。もし、真似をするならくれぐれも自己責任でお願いします。

HDDに少しでも詳しい人なら、なんて無謀なと思うでしょう。そもそもHDDは超精密機器で、読み取りヘッドは、ディスクの回転による風圧で、極わずか浮いているにすぎません、万が一、埃がその隙間に入り込もうものなら、ヘッドがディスクに接触して傷がついてしまいます。一度傷がついたら、そこをヘッドが通過するたび、傷が広がり、致命傷に・・・

ですが、私には少しだけ勝算がありました。 HDDを分解することの問題点は埃が入り込むこと。でも、毎分7200回転という高速で回転するディスクですから、乾いた埃であれば、その回転によって外周部に吹き飛ばされるはず。外周部にはそれを受け止めるフィルターが通常入っています。ですから、吹き飛ばされる前に、埃とヘッドが衝突しない限り、致命傷にはならないと・・・r0010006

そういう都合のいい予測をたてつつ、まず、分解します。シールをはがし、トルクスのねじをすべてはずします。分解した内部の状態。結構ほこりが入ってしまいました。



はずした蓋に窓をつけます。ハンドニブラーという工具で穴をあけます。そこに透明なプラスチックの板を貼り付けます。今回は、CD-ROMケースを切ってつかいました。

r0010011貼り付けには、弾力性と気密性がよさそうなセメダインスーパーX

接着剤が固まったところで、エアーダスターでディスク上面のほこりをできるだけ吹き飛ばします。

加工した蓋をねじでじっかり止めつけて完成。


裸のまま、USB-SATAアダプタで接続しました。すると、意外なことに(思ったとおり!?)無事認識し、フォーマットも順調にすすみました。r0010007

写真では、34%ですが、このまま100%になり、いくつかファイルを保存しましたが、無事読み書きでき、そのときのヘッドの動きもよく見えました。大成功!

分解前は不調だったのに、いまはそのそぶりもありません。おそらくHDDの不良セクタ代替が終わったのでしょう。USBでは S.M.A.R.T. が見れないので確認できませんが。

とにかくそんなわけで、無事シースルーHDDは完成。こんなにきちんと動作するなら、もっと綺麗に仕上げておけばよかった。残念

電解コンデンサの交換

数年前によく話題に上った電解コンデンサのトラブル。最近はあまり聞きませんが、中古の機器を買うとそのころのモノにあたるせいか、我が家でもいくつかの電解コンデンサが液漏れを起こしていました。

Mini-ITXマザーのME6000や、Mini-ITX用ケースの電源ユニット、オークションで落としたLHD-NASなどで見つかっています。今回は、Mini-ITXケースに付属のDC-DC電源のコンデンサ交換をしました。


液漏れしたコンデンサ

液漏れしたコンデンサ


液漏れしたコンデンサの写真。

中央の4つのコンデンサの3つから液漏れしています。のこり1つもかなりふくらんでいて、破裂寸前です。

まず、このコンデンサをはずします。裏面の半田部分に新しい半田を少し足してから、よく熱します。半田が十分溶けたらコンデンサを傾けるようにして、溶かしたほうの足を少し持ち上げます。今度は反対の足の半田を溶かし、逆方向に傾ける。これを交互に繰り返し、取り外します。

4つともはずしたら、穴に残った半田を吸い取ります。裏面から半田ごてをあて、よく溶かしたら、表面から半田吸い取り器で吸い取ります。

そのとき、バイスで基板を垂直に固定するとやりやすいです。


半田吸い取り中

半田吸い取り中


とりはずしたコンデンサは、6.3V 1000μF 、4本とも容量が100~300μF程度まで低下していました。

交換するコンデンサは、6.3Vのものが手に入らなかったので、やや背が高くなるが、16Vの1000μF 低ESRのニチコンHM(共立エレショップで購入)に交換


液漏れしたコンデンサ

液漏れしたコンデンサ



e4baa4e68f9be382b3e383b3e38387e383b3e382b5

新しいコンデンサ


 


コンデンサ交換後

コンデンサ交換後


LogitecのNAS LHD-NASを修理する

オークションでLogitecのNAS(ネットワーク接続のHDDのこと)を落としました。

このNASはMini-ITX規格のマザーボードを搭載したPCそのもので、Linuxを入れたりして遊んでみようかと思います。

オークションの説明には、HDDをフォーマットしてあり、商品としては機能しないあったのですが、どうせOSを入れなおすの問題無し。

ところが、物がとどいてみると、起動しない。裏蓋をはずし、モニタとキーボードを接続してテストをするが、一瞬起動してすぐに電源が落ちてしまう。試しに、256MB×2で搭載されているメモリを1枚はずしてみると無事起動、CD-ROMをつないでDebianをインストールしました。

しかし!再起動時に、また勝手に電源が落ちる。しかも、1度電源コードを抜かないと再起動しない。lhdnas-dengen1もしやと思い、電源ユニットをばらしてみると、電解コンデンサが液漏れを起こしていました。で、電解コンデンサの交換。写真は交換後のもの。

ついでに、異音がしていたファンの修理をしておきました。

組み上げて電源を入れると、無事起動。はずしたメモリを戻し再度起動・・・OK!

修理成功!

しかし、この品物ケースをあけてみると、いろいろ触ったあとがあった。おそらく調子が悪いのであけて調べたんだろうけど・・・。壊れているのがわかっていたらオークションの出品時にちゃんと書いておいてほしいなぁ、症状をきちんと書いておけば修理できる人が落札するのに。今回はたまたま修理できたけど、そうでない人が落札したらかわいそうなことに。

みなさんも、オークションには気をつけよう!たとえ出品者の評価がよかったとしても。

不誠実な出品者だとしても悪い評価をつければ、報復で自分にも悪い評価をされてしまいます。だから、それを恐れみんな不満があっても悪い評価は付けられないのです。

修理が終わり、48時間の負荷テストを無事終えたので記念撮影

lhdnas1

CPU:VIA C3-533MHz

MEMORY:512MB SDR-DIMM

HDD:160GB PATA(7200rpm)

 

 

ファンの修理

PCには電源やCPU、チップセットなどにDC FANがついていますが、ときどき故障したり異音がしたりと厄介です。

今回は、LogitecのNASの電源の冷却FANから異音がするので修理してみました。lhdnas-fan1

4cmmの小型FANでスペックをみると静音タイプのようです。このFANからカラカラと大きな異音がでていました。

これらのDC FANの特徴は、通常のモータではなく、回転部分との接点になるブラシをもたないブラシレスモーターになっていることです。寿命の短いブラシではなく、トランジスタ(FET)で電流の向きを切り替えて永久磁石を貼りつけたローターを回します。そのため、ベアリングさえ痛まなければ寿命は半永久的です。

  1. まず、羽根についたほこりをエアダスターで吹き飛ばします。
  2. フレームにゆがみや傷がないか確認
  3. ラベルのシールを慎重に3分の2くらいはがします。
  4. すると軸受けが見えるので、そこに注油します。
  5. ラベルを元通り貼り付け、ラベルが上の状態で、しばらく静置し、なじませます。

このときの注意点は

  • ラベルをはがしたときに、元通り貼り付けられるように、丁寧にはがし、手の油等つかないようにすること
  • 注油の際は、すこし粘りのある機械油を少量、楊枝の先などでたらします。556のようなさらさらした油は不可です。車のエンジンオイルでもいいですね。

lhdnas-fan2修理後、ケースに取り付けるまえに回転を確かめます。最初は、少し異音がありましたがだんだんとオイルがなじみ、かなり静かになりました。いちおう許せる範囲の騒音になったのでよしとしました。

取り付けの際にも、フレームが歪まないように慎重に取り付けます。雑につけると、フレームが歪み、軸がぶれたり、羽根がフレームにすれたりしてしまいます。