- 回路図
- サーボモーター制御用のGPIOピンでPWM信号を生成する
- ロボットアーム用のPIC16F8771Aのプログラミング
- PICロボットアームコードのシミュレーション
- EasyEDAを使用したPCB設計
- オンラインでのサンプルの計算と注文
- PICロボットアームの動作
自動車製造業の組立ラインから宇宙の遠隔手術ロボットまで、ロボットアームはいたるところにあります。これらのロボットのメカニズムは人間に似ており、同様の機能と機能の向上をプログラムできます。それらは、人間よりも速く正確に繰り返し行動を実行するために使用することができ、または人間の生命を危険にさらすことなく過酷な環境で使用することができます。Arduinoを使用して記録と再生のロボットアームをすでに構築しました。これは、特定のタスクを実行するようにトレーニングして、永遠に繰り返すことができます。
このチュートリアルでは、業界標準のPIC16F877A 8ビットマイクロコントローラーを使用して、ポテンショメーターで同じロボットアームを制御します。このプロジェクトの課題は、PIC16F877AにはPWN対応のピンが2つしかないことですが、ロボットには5つの個別のPWMピンを必要とする約5つのサーボモーターを制御する必要があります。したがって、GPIOピンを利用し、タイマー割り込みを使用してPICGPIOピンでPWM信号を生成する必要があります。もちろん、より優れたマイクロコントローラーにアップグレードしたり、デマルチプレクサICを使用して、ここでの作業を大幅に簡単にすることもできます。しかし、それでも、このプロジェクトに学習体験を試してみる価値はあります。
このプロジェクトで使用しているロボットアームの機械的構造は、前のプロジェクトで完全に3Dプリントされました。完全な設計ファイルと組み立て手順はここにあります。または、3Dプリンターをお持ちでない場合は、リンクに示されているように、段ボールを使用して簡単なロボットアームを作成することもできます。どういうわけかロボットアームを手に入れていると仮定して、プロジェクトに進みましょう。
回路図
このPICマイクロコントローラーベースのロボットアームの完全な回路図を以下に示します。回路図はEasyEDAを使用して描かれました。
回路図は非常に単純です。プロジェクト全体は12Vアダプターから電力を供給されます。この12Vは、2つの7805電圧レギュレータを使用して+ 5Vに変換されます。 1つは+ 5Vとラベル付けされ、もう1つは+ 5V(2)とラベル付けされます。レギュレーターが2つある理由は、サーボが回転すると大量の電流が引き込まれ、電圧降下が発生するためです。この電圧降下によりPICが自動的に再起動するため、PICとサーボモーターの両方を同じ+ 5Vレールで動作させることはできません。したがって、+ 5Vとラベル付けされたものはPICマイクロコントローラー、LCD、およびポテンショメーターに電力を供給するために使用され、+ 5V(2)とラベル付けされた別のレギュレーター出力はサーボモーターに電力を供給するために使用されます。
0Vから5Vまでの可変電圧を提供するポテンショメータの5つの出力ピンは、PICのアナログピンAn0からAN4に接続されています。タイマーを使用してPWMを生成することを計画しているため、サーボモーターは任意のGPIOピンに接続できます。サーボモーターにはRD2からRD6のピンを選択しましたが、任意のGPIOを選択できます。
プログラムには多くのデバッグが含まれるため、16x2LCDディスプレイもPICのポートBに接続されます。これにより、制御されているサーボモーターのデューティサイクルが表示されます。これとは別に、将来センサーを接続する必要がある場合に備えて、すべてのGPIOピンとアナログピンの接続も拡張しました。最後に、プログラマピンH1を接続して、ICSPプログラミングオプションを使用してpickit3でPICを直接プログラムしました。
サーボモーター制御用のGPIOピンでPWM信号を生成する
回路の準備ができたら、サーボモーターを制御するためにPICのGPIOピンでPWN信号を生成する方法を理解する必要があります。タイマー割り込み方式を使用して同様の何かをすでに疲れさせて、成功しました。ここではその上に構築するだけなので、ここが初めての場合は、先に進む前にこの前のチュートリアルを読むことを強くお勧めします。
すべてのホビーサーボモーターは50Hzの周波数で動作します。サーボモーターの1つの完全なパルスサイクルは、20msである1/50(F = 1 / T)になります。この完全な20msのうち、制御信号は0〜2msであり、残りの信号は常にオフです。次の図は、合計20msの持続時間の0度から180度までモーターを回転させるために、オン時間が0から2msまでしか変化しないことを示しています。
これを念頭に置いて、PICがポテンショメータから0から1204を読み取り、サーボモーターのデューティサイクルとなる0から100にマッピングするようにプログラムを作成する必要があります。このデューティサイクルを使用して、サーボモーターのオン時間を計算できます。次に、タイマー割り込みを初期化して、Arduinoのmillis()関数と同様に動作するように一定の間隔でオーバーフローするようにします。これにより、ステータスGPIOピンを希望の期間ハイに切り替え、20ミリ秒(完全な1サイクル)後にオフにして、同じプロセスを繰り返すことができます。これで、ロジックを理解したので、プログラムに取り掛かりましょう。
ロボットアーム用のPIC16F8771Aのプログラミング
いつものように、ビデオ付きの完全なプログラムはこのページの最後にあります。コードはここから必要なすべてのファイルとともにダウンロードすることもできます。このセクションでは、プログラムの背後にあるロジックについて説明します。このプログラムは、ADCモジュール、タイマーモジュール、およびLCDモジュールを使用してロボットアームを制御します。ADC機能やタイマー機能の使用方法やLCDとPICのインターフェース方法がわからない場合は、それぞれのリンクに戻ってそれらを学ぶことができます。以下の説明は、読者がこれらの概念に精通していることを前提としています。
タイマー0ポート構成
コードの最も重要なセクションは、特定の遅延ごとにタイマー0をオーバーフローに設定することです。この遅延を計算する式は、次のように与えることができます。
遅延=((256-REG_val)*(Prescal * 4))/ Fosc
OPTION_REGおよびTMR0レジスタを使用することにより、タイマー0をプリスカラー値32で動作するように設定し、REG値を248に設定しました。ハードウェアで使用される水晶周波数(Fosc)は20Mhzです。これらの値を使用して、遅延は次のように計算できます。
遅延=((256-248)*(32 * 4))/(20000000) = 0.0000512秒(または) = 0.05ミリ秒
これで、0.05msごとにオーバーフローするようにタイマーを設定しました。同じことを行うためのコードを以下に示します
/ *****タイマーのポート構成****** / OPTION_REG = 0b00000100; //外部周波数と32をプリスケーラとして持つTimer0 //プルアップも有効にし ますTMR0 = 248; //0.0001秒の時間値をロードします; delayValueは、 TMR0IE = 1 のみで0〜256の範囲にすることができます。// PIE1レジスタのタイマー割り込みビットを有効にするGIE = 1; //グローバル割り込みを有効にする PEIE = 1; //ペリフェラル割り込みを有効にする / *********** ______ *********** /
サーボモーターの合計0msから2msの制御ウィンドウのうち、0.05ミリ秒の分解能で制御できます。これにより、0度から180度の間でモーターの40の異なる位置を(2 / 0.05)持つことができます。MCUがより多くの位置と正確な制御を取得するためにサポートできる場合は、この値をさらに減らすことができます。
割り込みサービスルーチン(ISR)
0.05msごとにタイマー0がオーバーフローに設定されたので、TMR0IF割り込みフラグが0.05msに設定されます。したがって、ISR関数内で、そのフラグをリセットし、countという変数 を1つインクリメントできます。したがって、この変数は0.05msごとに1ずつ増加します。
void interrupt timer_isr() { if(TMR0IF == 1)//タイマーオーバーフローが原因でタイマーフラグがトリガーされました-> 0.05msごとにオーバーフローするように設定されています { TMR0 = 248; //タイマー値をロードし ますTMR0IF = 0; //タイマー割り込みフラグ カウントを クリアします++; //0.05msごとに1ずつカウントします}
デューティサイクルとオンタイムの計算
次に、5つのサーボモーターすべてのデューティサイクルとオンタイムを計算する必要があります。 5つのサーボモーターがあり、それぞれがアームの個々のセクションを制御するために使用されます。したがって、5つすべてのADC値を読み取り、それぞれのデューティサイクルとオンタイムを計算する必要があります。
ADC値は0から1024の範囲になり、取得した値に0.0976(100/1024 = 0.0976)を掛けるだけで、0%から100%のデューティサイクルに変換できます。次に、この0〜100%のデューティサイクルをオン時間に変換する必要があります。 100%のデューティサイクルでは、オン時間は2ms(180度の場合)である必要があるため、0.02(2/100 = 0.02)を乗算すると、0から100のデューティサイクルが0から2msに変換されます。しかし、タイマー変数のカウントは、0.05msごとに1回増加するように設定されています。これは、カウントの値が1msごとに20(1 / 0.05 = 20)になることを意味します。したがって、20に0.02を掛けて、プログラムの正確な時間どおりに計算する必要があります。これにより、値0.4(0.02 * 20 = 0.4)が得られます。同じコードを以下に示します。forループを使用して、5つのポットすべてに対して5回繰り返されていることがわかります。結果の値はT_ON配列に格納されます。
for(int pot_num = 0; pot_num <= 3; pot_num ++) { int Pev_val = T_ON; POT_val =(ADC_Read(pot_num)); // ADCを使用してPOTの値を読み取ります Duty_cycle =(POT_val * 0.0976); // 0から1024から0から100に マップT_ON = Duty_cycle * 0.4; // 20 * 0.02
回転させるモーターの選択
5つのモーターすべてを一緒に制御することはできません。ISRコードが重くなり、マイクロコントローラー全体の速度が低下するためです。したがって、一度に1つのサーボモーターのみを回転させる必要があります。マイクロコントローラを回転させるサーボを選択するには、5つのサーボモーターすべてのオン時間を監視し、それを以前のオン時間と比較します。オン時間に変化がある場合は、特定のサーボを移動する必要があると結論付けることができます。そのためのコードを以下に示します。
if(T_ON!= Pev_val) { Lcd_Clear(); サーボ= pot_num; Lcd_Set_Cursor(2,11); Lcd_Print_String( "S:"); Lcd_Print_Char(servo + '0'); if(pot_num == 0) {Lcd_Set_Cursor(1,1); Lcd_Print_String( "A:");} else if(pot_num == 1) {Lcd_Set_Cursor(1,6); Lcd_Print_String( "B:");} else if(pot_num == 2) {Lcd_Set_Cursor(1,11); Lcd_Print_String( "C:");} else if(pot_num == 3) {Lcd_Set_Cursor(2,1); Lcd_Print_String( "D:");} else if(pot_num == 4) {Lcd_Set_Cursor(2,6); Lcd_Print_String( "E:");} char d2 =(Duty_cycle)%10; char d1 =(Duty_cycle / 10)%10; Lcd_Print_Char(d1 + '0'); Lcd_Print_Char(d2 + '0');
また、サーボのデューティサイクルをLCD画面に印刷して、ユーザーが現在の位置を認識できるようにします。ON時間の変化に基づいて、可変サーボは0から4までの数字で更新され、それぞれが個々のモーターを表します。
ISR内のサーボモーターの制御
ISR内では、0.05msごとに変数カウントがインクリメントされます。これは、1msごとに変数が20ずつインクリメントされることを意味します。これを使用して、PWM信号を生成するようにピンを制御する必要があります。countの値がオン時間よりも小さい場合、そのモーターのGPIOは次の行を使用してオンになります
PORTD = PORTD-サーボコード;
ここで、配列servo_codeには、5つのサーボモーターすべてのピンの詳細があり、可変サーボの値に基づいて、その特定のサーボモーターのコードが使用されます。次に、既存のPORTDビットと論理的にOR(-)するため、他のモーターの値を乱さず、この特定のモーターのみを更新します。同様にピンをオフにします
PORTD = PORTD&〜(servo_code);
論理逆(〜)演算子を使用してビット値を反転し、PORTDでAND(&)演算を実行して、他のピンを前の状態のままにして、目的のピンのみをオフにしました。完全なコードスニペットを以下に示します。
void interrupt timer_isr() { if(TMR0IF == 1)//タイマーオーバーフローが原因でタイマーフラグがトリガーされました-> 0.05msごとにオーバーフローするように設定されています { TMR0 = 248; //タイマー値をロードし ますTMR0IF = 0; //タイマー割り込みフラグ カウントを クリアします++; //カウントは0.05msごとに1ずつ増加します->カウントは1msごとに20になります(0.05 / 1 = 20))} int Servo_code = {0b01000000、0b00100000、0b00010000、0b00001000、0b00000100}; if(count> = 20 * 20) count = 0; if(count <=(T_ON))PORTD = PORTD-サーボコード; else PORTD = PORTD&〜(servo_code); }
GPIOピンが再びオンになる前に、合計サイクルが20ミリ秒続く必要があることがわかっています。したがって、カウントの値を400と比較してカウントが20ミリ秒を超えているかどうかを確認し(上記と同じ計算)、はいの場合は、カウントを再度ゼロに初期化する必要があります。
PICロボットアームコードのシミュレーション
実際のハードウェアにコードを取り込む前に、コードをシミュレートすることをお勧めします。そこで、Proteusを使用してコードをシミュレートし、正しく機能することを確認しました。シミュレーションに使用した回路を以下に示します。必要に応じてPWM信号が生成されているかどうかをオシロスコープで確認しました。また、LCDモーターとサーボモーターが期待どおりに回転しているかどうかを確認できます。
ご覧のとおり、LCDには、3番目のモーターであるポット値に基づいてモーターDのデューティサイクルが07と表示されます。同様に、別のポットを移動すると、そのポットのデューティサイクルとそのモーター番号がLCDに表示されます。オシロスコープに表示されるPWM信号を以下に示します。
合計サイクル周期は、オシロスコープのカーソルオプションを使用して22.2msと測定されます。これは、目的の20msに非常に近い値です。最後に、コードが機能することを確認しました。回路を続行するには、パフォーマンスボードにはんだ付けするか、PCBを使用します。POTは接続不良のために常に問題を引き起こす傾向があるため、ブレッドボードでは簡単に機能しません。
EasyEDAを使用したPCB設計
このPICロボットアームを設計するために 、EasyEDAと呼ばれるオンラインEDAツールを選択しました。私は長い間それを使用してきました、そしてそれはフットプリントの広大な利用可能性と使いやすい性質のために非常に便利だと思います。PCBを設計した後、低コストのPCB製造サービスでPCBサンプルを注文できます。また、電子部品の在庫が豊富で、ユーザーがPCBの注文と一緒に必要な部品を注文できる、部品調達サービスも提供しています。
回路とPCBを設計する際に、回路とPCBの設計を公開して、他のユーザーがそれらをコピーまたは編集して作業を活用できるようにすることもできます。また、この回路の回路とPCBのレイアウト全体を公開しました。確認してください。以下のリンク:
easyeda.com/circuitdigest/pic-development-board-for-robotic-arm
このリンクを使用すると、このプロジェクトで使用しているものと同じPCBを直接注文して使用できます。設計が完了すると、ボードは3Dモデルとして表示できます。これは、製造後にボードがどのように表示されるかを視覚化するのに非常に役立ちます。使用しているボードの3Dモデルを以下に示します。これとは別に、ボードの最上層と最下層を表示して、滑らかな画面が期待どおりかどうかを確認することもできます。
オンラインでのサンプルの計算と注文
このPICロボット PCBの設計が完了したら、 JLCPCB.comからPCBを注文できます。 JLCPCBからPCBを注文するには、ガーバーファイルが必要です。 PCBのガーバーファイルをダウンロードするには、 EasyEDAエディターページの [Generate Fabrication File ]ボタンをクリックし、そこからガーバーファイルをダウンロードするか 、下の画像に示すように[ Order atJLCPCB ]をクリックします 。これにより、JLCPCB.comにリダイレクトされます。ここで、注文するPCBの数、必要な銅層の数、PCBの厚さ、銅の重量、さらにはPCBの色を選択できます(以下に示すスナップショットのように)。
すべてのオプションを選択したら、[カートに保存]をクリックすると、EasyEDAからダウンロードしたガーバーファイルをアップロードできるページが表示されます。ガーバーファイルをアップロードし、「カートに保存」をクリックします。そして最後に[安全にチェックアウト]をクリックして注文を完了します。数日後にPCBを入手できます。彼らは2ドルという非常に低いレートでPCBを製造しています。ビルド時間も非常に短く、DHLで3〜5日で48時間です。基本的に、注文から1週間以内にPCBを入手できます。
PCBを注文した後、PCB の 製造進捗状況 を日付と時刻 で確認 できます。アカウントページで確認し、「制作進捗状況」をクリックしてください。
PCBを注文して数日後、下の写真に示すように、PCBサンプルを素敵なパッケージに入れました。
そして、これらの部品を入手した後、必要なすべてのコンポーネントをPCBにはんだ付けしました。また、接続線を使用する代わりに、POTを直接はんだ付けしました。これは、最初に使用した雌線から雌線に、おそらく接触が緩んでいるために奇妙なアナログ出力電圧が発生するためです。すべてのコンポーネントが組み立てられると、私のPCBは次のようになりました。
このボードには7805が1つしかないことに気づいたかもしれません。それは、最初はPICとサーボモーターの両方に電力を供給するためのレギュレーターだけで済ませることができると思っていたのですが、後で2つ必要だと気づいたからです。そこで、外部回路を使用して、ここに表示されている緑色のワイヤーを介してサーボモーターに電力を供給しました。
それにもかかわらず、あなたはそれについてあまり心配する必要はありません。PCBに変更を加えました。変更されたPCBを利用して、両方のレギュレーターをボード自体にはんだ付けできます。
PICロボットアームの動作
すべての疲れた仕事の後、それは報いの時間です。ボード上のすべてのコンポーネントをはんだ付けし、プログラムをPICコントローラーにアップロードします。完全なコードを以下に示すか、ここからダウンロードできます。ボードに付属のプログラミングコネクタは、Pickit3を使用してプログラムを直接アップロードするのに役立ちます。プログラムがアップロードされると、現在制御されているサーボを表示するLCDが表示されます。PICマイクロコントローラーのプログラミングの詳細については、前のチュートリアルに従ってください。
そこから、ポットを回して、サーボモーターが各ポテンショメーターにどのように応答するかを確認できます。フォーマットを理解したら、ロボットアームを制御して、実行するために必要なアクションを実行し、楽しむことができます。プロジェクトの完全な動作は、以下にリンクされているビデオで見つけることができます 。
つまり、皆さんがプロジェクトを理解し、そこから何か新しいことを学んだことを願っています。質問がある場合は、コメントセクションに残すか、フォーラムを使用して他の技術的な議論を行ってください。