• ベストアンサー

PIC16F84A PWM制御でトラブル。・゜・(ノД`)・゜・

PIC16F84Aでサーボを動かすためにDelay関数を用いたPWMのプログラムを組んだのですが、picの電源を安定化電源にすると問題なく動作するのですが、乾電池(4本直列)につなぐと動作が不安定になってしまいます・・。 安定化電源、乾電池共に電圧は5.6V程度で、電流の問題かと思い、乾電池(4本直列パック)を並列に繋いで見たのですが改善されませんでした。 また、サーボ自体には問題はなく、picからのパルス出力そのものが不安定になっていることは確認出来ました。 リモコンカーに搭載するため、安定化電源ではなく、乾電池で動作させたいのですが、どうしたらいいのかお手上げ状態です・・ 今週末に動かしたいので、どなたかお助け願います。・゜・(ノД`)・゜・

質問者が選んだベストアンサー

  • ベストアンサー
  • zwi
  • ベストアンサー率56% (730/1282)
回答No.1

状況から推測するとソフトが原因とは思えません。ハード側に何らかの問題があると思われます。 回路図見てないので何とも言えませんが、乾電池で動作しているときに、電圧が不安定になっている事が一番考えれる原因です。 サーボの電源とPICの電源は共通なのでしょうか? ちゃんと乾電池→安定化電源回路→PICになってますか? サーボ動作時にクロックは安定していますか?サーボのノイズの影響を受けていませんか?

その他の回答 (2)

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.3

★高校生時代を思い出して。 >picの電源を安定化電源にすると問題なく動作するのですが、 >乾電池(4本直列)につなぐと動作が不安定になってしまいます・・。  ↑ ・単純に電圧が足りないだけかもよ。  4本直列にして何で 5.6V なの?  乾電池なら 1.5V×4=6.0V になるでしょうが…。  充電池なら 1.2V×4=4.8V だから 5.6V だと計算合わないね。  充電したばかりだと 1.4V×4=5.6V になるが、でも負荷を掛けると 4.8V になりそうだね。  充電地を使っているのならば5~6本にしてみたらどう?電圧は 6.0V~7.2V で使う。 ・電池駆動でも安定化電源回路(三端子レギュレータIC)を通した方がノイズなどの影響を  受けにくくなります。また、三端子レギュレータ IC の出力電圧が 5.0V なら最低でも  6.5V~7.5V の電圧が必要です。三端子レギュレータ IC は使っている?型番は?何? >安定化電源、乾電池共に電圧は5.6V程度で、電流の問題かと思い、  ↑  電圧が同じで乾電池の場合に動作が不安定という事はノイズが電源を伝わり PIC16F84A に  影響を及ぼしているような気がします。IC の電源付近にパスコンなどを入れていますか?  あと電源をアナログ部とデジタル部に分けたほうが良いかも。  特に大電力を使うアナログ部とデジタル部(IC)などは三端子レギュレータ IC を使って  電源を分けると良いと思います。 ・他にも基板で GND ラインは外周をループするようにつなげれば電位差とか起きなかったり  ノイズにも強くなります。基板のパターンも含め調査してみて下さい。 >リモコンカーに搭載するため、安定化電源ではなく、 >乾電池で動作させたいのですが、どうしたらいいのかお手上げ状態です・・  ↑  三端子レギュレータ IC を使って電圧を安定させるべきかな。  使っていないでしょ三端子レギュレータ IC など。 ・以上。

unauthorized
質問者

お礼

沢山の情報ありがとうございました! おかげさまで動作させることが出来ました! 最終的にはレギュレータ回路無しでもちゃんと動くまでになりましたが、レギュレータも初めて自作し、大変勉強になりました! どうもありがとうございました!

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.2

ちょっと訂正。 >ちゃんと乾電池→安定化電源回路→PICになってますか? 乾電池→電源IC→PICになってますか? 追加で、電源ICの出力電圧は何Vでしょうか? 安定化電源時と乾電池の電位差で安定度が変わるのなら、PIC用の電源IC周りが怪しいです。

unauthorized
質問者

お礼

ご回答ありがとうございました! おかげさまで動作させることができました! 安定化回路というものを一切使っていませんでしたので 3端子レギュレータとNOT回路のICをいれ、プログラムも少し改良してようやく動作しました。 どうやらノイズの出やすい回路設計に加え、ノイズを拾いやすいプログラミングだったのが良くなかったようです。 頂いた書き込みが良いヒントに繋がりました。 どうもありがとうございました!

関連するQ&A

  • PIC16F627Aを低電圧で動かすには

    PIC16F627Aです 電池で駆動するプログラムを書いていてうまく動かないので 5V安定化電源につないだら動きました。 確かめるために BポーがをHIにするところでストップするようにして確かめました。 4.4Vでは動作しません。5Vでは動作します。 プログラムは下記です。 このPICは3Vから動作すると思いますが低電圧で 動かすために特別な設定が必要なのでしょうか。 あるいは小生の設定に問題があるのでしょうか。 ご教授ください。   TRISA = 0xFF;   TRISB = 0x01; CCP1CON = 0x0C; PR2 = 0x19; CCPR1L = 0x0C; CCP1CON = PWM_STOP;   T2CON = 0x0C; T1CON = 0x01; TMR1L = 0; TMR1H = 0; TMR1IF = 0; TMR1IE = 1; PORTA = 0x00; PORTB = 0xFF;   ここで4.4V(電池)ではPORTB がHIになりません。   5V電源ではHIになります。   電圧チェックおよびダイオード発光で確認しました while(1) {;}; 以下省略

  • 電池動作の省電力PIC回路

    単三電池直列3本で555タイマーからの出力でスイッチングし、PIC制御のLED(約150mA消費)を光らせたいのですが、、スイッチングをトランジスタで行ったところ、PICに十分な電流が届いていないか、電流が安定していないかで、うまく動きません。 PICは電源に直接スイッチングすることで動作します。 (入力ではなく電源です。ここは変えられません) リレーで動作はすでにやっておりますが、リレーって消費電力が高そうで電池だとどうなのかといったところです。 スイッチングをするのによい方法はありますか?

  • PICのPWMの使い方を教えてください

    PIC12F1822のPWMのテストをしていますが、正しい設定方法が判らず、以下の現象が出ています。 プログラム全体と、MPLIB のシミュレータによるLogic Analyzerの画像を添付しましたので、PICにお詳しい方のアドバイスをよろしくお願いいたします。 ◆ テスト内容: 周波数一定でデューティー比を変化させていく  今回の設定は、PR2=127 なので、パルス幅を0 ~ 最大パルス幅の 511 ((PR2+1)*4)で変化させる ●問題点1: デューティー比100%近く(508/512)でPWM出力が突然 50%に変わる。 ●問題点2: デューティー比100%以上(512/512以上)を設定するとPWMは100%('H'のまま)となる。 その後デューティ比を下げてもPWMの出力は'H'のままで、PWMの出力が出ない。 ● 問題点3: パルス幅の設定で、CCP1CON<5:4>に'00'以外をセットすると、PWMの動作がおかしくなる(出力が'H'のまま) ・・・ これはシミュレータのバグでしょうか? プログラム全体は、一番下にありますが、メインロジックは以下のように簡単なものです。 while (1) { for (i = 500; i <= 512; i = i + 1) { pulse_width = i ; CCPR1L = pulse_width >> 2; // パルス幅上位8bit CCP1CON = ((pulse_width & 0x0003) << 4) | 0x0C; // パルス幅下位2bit         // ここで、CCP1CON<5:4>に'00'以外をセットすると、PWMの動作がおかしくなる __delay_ms(1); } } どうぞよろしくお願いいたします。                           K.A. --------------------------------------------- /* * File: 周波数一定、ディューティー比連続変化 * Author: K.A. * * Created on 2014/07/20 * */ #include <stdio.h> #include <stdlib.h> #include <xc.h> #pragma config FOSC=INTOSC, WDTE=OFF, PWRTE=ON, BOREN=ON, MCLRE=OFF #define _XTAL_FREQ 8000000 // クロック8MHz #define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0))) int main(int argc, char** argv) { OSCCON = 0b01110010; // 内部クロックは8MHz ANSELA = 0b00000000; // すべてをデジタルI/Oに割当 TRISA = 0b00001000; // すべてのピンは出力に割当てる(RA3は入力専用) PORTA = 0b00000000; // 出力ピンの初期化(全て'0'にする) RA5 = 0; // 動作確認用LED /* PWM */ TRISA2 = 1; // RA2 出力をサスペンド TMR2IF = 0; // TMR2 フラグをクリア CCP1SEL = 0b0; // CCP1/P1Aの機能をRA2に割り当てる CCP1CON = 0x0C; // PWM モード // Period を 設定する xx ms=((PR2)+1)*4*125ns(8MHz)* PreScaler(x1-x64) PR2 = 127; // 0.064ms (プリスケーラが x1 の場合) T2CKPS0 = 0b0; // プリスケーラ 00:x1, 01:x4, 10:x16, 11:x64 T2CKPS1 = 0b0; // CCPR1L = 0; // パルス幅上位8bit CCP1CON = ((0 & 0x0003) << 4) | 0x0C; // パルス幅下位2bit TMR2ON = 1; // TMR2 カウント開始 while (TMR2IF == 0) { /** / do nothing /**/ } TRISA2 = 0; // RA2に出力を接続 unsigned int pulse_width; int i; while (1) { // パターン1 : デューティー比を変化させていく // 今回の設定は、PR2=127 なので、最大パルス幅は 511 ((PR2+1)*4) // 問題点1: デューティー比100%近く(508/512)でPWM出力が突然 50%に変わる。 // 問題点2: デューティー比100%以上(512/512以上)を設定するとPWMは100%('H'のまま)となる。 // その後デューティ比を下げてもPWMの出力は'H'のままで、PWMの出力が出ない。 // 問題点3: パルス幅の設定で、CCP1CON<5:4>に'00'以外をセットすると、PWMの動作がおかしくなる(出力が'H'のまま) for (i = 500; i <= 512; i = i + 1) { pulse_width = i ; // Pulse width を 設定する PW=(CCPR1L:CCP1CON<5:4>)*125ns(8MHz)*PreScaler(x1-x64) CCPR1L = pulse_width >> 2; CCP1CON = ((pulse_width & 0x0003) << 4) | 0x0C; // CCP1CON<5:4>に'00'以外をセットすると、PWMの動作がおかしくなる // printf("PR2= %d, PW= %d, CCPR1L= %x, DCIB= %x \n", PR2, pulse_width, CCPR1L, temp2) ; __delay_ms(1); if (RA5==1) RA5=0; else RA5=1 ; } } return (EXIT_SUCCESS); } ----------------------------------------

  • PIC16F84Aの動作電圧について

    PIC初心者です。PIC16F84Aを使用して外部からのコマンドに応じてパルス出力する回路を組みました。 現状問題なく動作しているのですが疑問がわきました。電源をOFFにしたとき電源回路側の都合で約20秒くらい掛けて0.5Vくらいまでゆっくりと低下して行きます。このときOFFにして0.6Vくらいの段階で再び電源をONにするとPICが初期化されず前に送ったコマンド(設定)を覚えていて改めて設定しなくても動いてしまうことに気づきました。電源電圧が0.6Vのような低い電圧になっても設定は覚えてられる物なのでしょうか? どなたか教えていただけると助かります。

  • PIC PWMをLEDドライバで駆動

    PICで生成したPWM信号をLEDドライバで駆動したいと考え添付の様な回路を作成し動作させました。 <問題点> PIC PWM出力直後のLEDは蛍の様に点滅をするのですが、ドライバ駆動のLEDはゆらゆら点滅になってしまいます。 尚、PIC PWMをON/OFF出力にした場合、連動してON/OFFしています。 <LEDドライバ amazon購入> ・入力範囲:DC 5-35V、出力700mA±20mA、1-10 3W LED駆動 ・PWM調光、ハイレベルオフ出力、低レベルの電源オン出力に対応 ・ステップダウン動作モードにより、LEDの総電圧差が入力電源電圧より2 – 3 V未満であることを保証します  ※ステップダウン動作モードが分かっていません 初心者ですので雑な作りかと思いますがご指摘を願いします。

  • PICでサーボモータ制御(C言語)

    個人的PICでのにサーボ制御をしてみようとしています。 まず、動作確認をしてみようとPIC(16F84A)を用いて、PICの基本回路を構成してあります。 次にサーボ制御をしてみようという事で、信号をRB1から得る事にします。 (電源、グランドはしっかり接続してあります) そこで、以下のプログラムを走らせてみました。 ※コンパイラはHI-TECH社の無料版を使っています。 #include<pic.h> #include<delay.h> main(void){ int a, b;    TRISA = 0x00;    TRISB = 0x00; while(1){ RB1=1; for(a=0;a<16;a++)DelayUs(100); //PointA RB1=0; for(b=0;b<186;b++)DelayUs(100); //PointB } } ※DelayUs関数はμsecの待ち発生関数です。 サーボが約20secのパルスということなので、動作確認のために組みました。 PointA,Bと記述した部分をいくら変動させても動作がかわらず一定の角度方向にしか動きません。 ただ、確認のために組んだプログラムなのですが、これではだめなのでしょうか?

  • PIC(16F628A)が壊れる理由

    本の記事を見ながらPICでLEDを光らせる回路を組んでいます。 16F628AというPICです。 過去3回、原因不明で同じPICが壊れてしまい(PICライタで書き込みエラーとなる)ました。 今回、最新の注意を払い、ブレッドボード上に実装し動作を確認後、 プリント基板に半田付けをしました。 最初は問題なく動いていたのですが、動作中に直流電源(DK-911というサンハヤトのキット)の電圧を5Vから3.3V以下に下げたところ突然LEDが消えてしまいました。 またPICが壊れたと思い、PICライタで書き込んでみると予想通りエラーが でました。 プリント板の回路に短絡がないか確認しましたが、特に問題はなさそう でした。 その後、何度かプリント板をつないでみましたが、全くLEDは光らず、 PICが非常に高温になっているため危険と思い諦めました。 今回PICが壊れた原因を考えると、電圧を下げたことくらいしか考えられません。 はたしてこの程度でPICが壊れるでしょうか。 PICが何度も壊れているため、自分で半田付けして作った直流電源に何か問題があるのでは?と考えることもありますが、常に電圧はテスターで開放時に5.4V程度と仕様通りであることを確認しています。 何か考えられる原因があれば教えていただきたいと思います。

  • モータをPWM駆動した際の電流について

    ┌── 電池 ── 電流計1 ── モータ ─ 電流計2 ────── FET ─┐ │ └ 電圧計 ┘        └←← ダイオード ←←┘           │ │                                            │ └──────────────────────────────┘ となるシンプルな回路でPWM制御によるモータ駆動のテストしています。 周期は24kHzで、モータは安いDCモータです。 ※実際にはHブリッジでかつゲートドライバが入っていますが省略しています。   また、Hブリッジの駆動にはデッドタイムを500nsほど入れています。 この回路における電流計1と電流計2で計測される値の意味が、分からなくて困っています。 任意のPWM比でFETをドライブした際に、電流計1 & モータ & 電流計2には、 ほぼ電圧計*PWM比の平均電圧が加わる考えており、 電流計1と電流計2の抵抗値と、FETによる抵抗値が十分小さければ 平均電圧のほとんどはモータに加わる。 電流計1ではPWMのON期間の電流のみが計測され、 電流計2ではダイオードで帰還する分も併せて計測している。 このため概ねでは、電流計2 = 電流計1/PWM比 の値となると考えています。 電圧計*電流計1が電池の消費電力(入力電力)であり、 少なくともモータをロックしておけば、モータに加わる出力電力は(電圧計*PWM比)*電流計2となり、 電圧計*電流計1 = (電圧計*PWM比)*(電流計1/PWM比)が成り立つと考えてよいでしょうか? モータが熱として捨てる以外の損失が無ければという前提ですが。 実際に計測してみた値は、電圧計=11.6V、PWM比=10%、モータはロックにおいて 電流計1=0.26A、電流計2=0.48Aでした。 これに対し、直流安定な電源として、充電乾電池1本を繋いでモータをロックして計測した際に、 電圧=0.85V、電流=0.394Aより、巻線抵抗=2.16Ωでした。 PWMで計測した際の値で、平均電圧=1.16V、電流=0.48Aがモータに加わっていれば 巻線抵抗=2.42Ωのため充電乾電池による結果と概ね一致します。 しかし、電流計1の値をどのように読み取れば良いのかが分かりません。 私の考え方では、電流計1=0.048Aでなければ入力電力=出力電力が成り立ちません。 お手数ですが、どこに間違えがあるのか御教授いただきたいです。

  • PWMのパルスを直流電圧にしたいです

    PWMのパルス幅によって電圧が0~5VとしてPICなどのADコンバータで入力して デジタルの数値として認識したいのですが、 パルス波形をDuty比に応じた直流電圧にするにはどんな回路をつければ良いでしょうか? またPWMの周波数は何ヘルツくらいが良いでしょうか? (周波数の上限、下限などがあったら教えていただきたいです)

  • PICのPWMの正しい使い方について教えてください

    PIC12F1822用のPWMの基本動作テストプログラムを作りましたが、PWM出力が意図どおりに得られません。 (XC8のテストプログラムを下に添付。テストパターン1/2の切り替えはコメントアウトをお願いします。  アナライザの出力を画像で添付しました。) テスト目的: タイマー0の周期割り込みに合わせて、PWMのデューティー比(または周期)を変更するプログラム   テストパターン 1 : パルスのデューティー比を変えるテスト 質問1: パルスのデューティー比を変えるテストは、PWM設定の一回おきにCCPからのPWMの出力が出ません テストパターン 2 : パルスの周波数を変えるテスト 質問2: 周波数を変えるテストはOKに見えるものの、1回目のPWMがHighとなるのと、割り込みの11回目、13回目あたりでPWM出力が欠落する 【回答のお願い】 どうも、PWMのレジスタ設定に手順、またはタイミングがあるのではないかと思いますが、原因がわからず困っております。 PICに詳しい方からのご指導をよろしくお願いいたします。                                    K.A. ------------------------------------------------------ /* * File: PIC12F1822 PWC * Author: K.A. * * Created on 2014/07/20 * * タイマー0の周期割り込みに合わせて、PWMのデューティー比(または周期)を変更するプログラム * */ #include <stdio.h> #include <stdlib.h> #include <xc.h> #pragma config FOSC=INTOSC, WDTE=OFF, PWRTE=ON, BOREN=ON, MCLRE=OFF #define _XTAL_FREQ 8000000 // クロック8MHz /* * */ // タイマー割込みの処理 int TMR0_Count = 0; // タイマーの割込み発生回数をカウントする変数 void interrupt Timer0(void) { // タイマー0の割込み発生か? Timer0 は 8bitの オーバーフロー・カウンタ if (TMR0IF == 1) { TMR0_Count++; if (TMR0_Count > 5) { TMR0_Count = 0; if (RA5 == 0) RA5 = 1; else RA5 = 0; // RA5は、動作表示用LED } TMR0IF = 0; // タイマー0割込フラグをリセット } } int main(int argc, char** argv) { unsigned int pulse_width = 5; OSCCON = 0b01110010; // 内部クロックは8MHz ANSELA = 0b00000000; // すべてをデジタルI/Oに割当 TRISA = 0b00001000; // すべてのピンは出力に割当てる(RA3は入力専用) PORTA = 0b00000000; // 出力ピンの初期化(全て'0'にする) RA5 = 0; // 動作確認用LED // Timer0  Timer0 は 8bitの オーバーフロー・カウンタ OPTION_REG = 0b00000001; // 内部クロックでTIMER0を使用、プリスケーラカウント値 1:2 // bit5:0=Fosc/4, bit3:0=PreScaler_ON, bit2-0:PreScaler TMR0 = 0; // タイマー0の初期化 (+2cycle) TMR0IF = 0; // タイマー0割込フラグを0にする TMR0_Count = 0; // 割込み発生の回数カウンターを0にする TMR0IE = 1; // タイマー0割込みを許可する GIE = 1; // 1: 全割込み処理を許可する /* PWM */ TRISA2 = 1; // RA2 出力をサスペンド TMR2IF = 0; // TMR2 フラグをクリア CCP1SEL = 0b0; // CCP1/P1Aの機能をRA2に割り当てる CCP1CON = 0x0C; // PWM モード // Period を 設定する xx ms=((PR2)+1)*4*125ns(8MHz)* PreScaler(x1-x64) PR2 = 127; // 4.096ms (プリスケーラが x64 の場合) T2CKPS0 = 0b1; // プリスケーラ 00:x1, 01:x4, 10:x16, 11:x64 T2CKPS1 = 0b1; // CCPR1L = pulse_width >> 2; // パルス幅上位8bit CCP1CON = ((pulse_width & 0x0003) << 4) | 0x0C; // パルは幅下位2bit TMR2ON = 1; // TMR2 カウント開始 while (TMR2IF == 0) { /** / do nothing /**/ } TRISA2 = 0; // RA2に出力を接続 while (1) { if (TMR0_Count == 0) { /**** テストパターン 1 : パルスのデューティー比を変えるテスト ****/ // パルスのデューティー比を変えるテストは、PWM設定の一回おきにCCPがPWMの出力が出ません。 なぜ? pulse_width = pulse_width + 10; if (pulse_width > 500) pulse_width = 5; /**/ /**** テストパターン 2 : パルスの周波数を変えるテスト **** / // 周波数を変えるテストはOKに見えるが、 // 1回目のPWMがHighとなるのと、割り込みの11回目、13回目あたりでPWM出力が欠落する PR2 = PR2 - 8 ; if (PR2 < 8) PR2 = 127; pulse_width = PR2 ; // Duty 25% に相当 /**/ CCPR1L = pulse_width >> 2; CCP1CON = ((pulse_width & 0x0003) << 4) | 0x0C; TMR0_Count++; // 続けて PWMの設定変更をしないためのフラグ代わり } } return (EXIT_SUCCESS); }

専門家に質問してみよう