ラジコンサーボを制御するためには、ラジコンサーボの回転角度の最小値と最大値を調べる必要があります。また、使い方にもよりますが、中心角度も必要です。そこで今回は、ラジコンサーボを制御するために必要な情報を取得するための装置を作成します。作成目的および仕様は以下の通りです。
<作成目的>
- ラジコンサーボのニュートラル位置の制御値の確認
- ラジコンサーボの最大角度の制御値の確認
- ラジコンサーボの最小角度の制御値の確認
制御値とはラジコンサーボに出力する信号の、ハイにしてる時間です。
<仕様>
- 7セグメントディスプレイに出力中の制御値を表示
- ニュートラル位置への動作を行う
- 正転
- 逆転
完成した「ラジコンサーボチェッカー」です。
ページ最後の動画も同じ動画です。
回路図およびプログラムに関する各種詳細は、以下の記事を参考にしてください。今回、7セグメントディスプレイはカソードコモンタイプを使用するので注意してください。
1.今回使用するPICについて
今回使用するPICは「PIC16F1829」です。
2.回路
2.1 電子回路図
2.2 電子回路の写真
2.3 回路説明
2.3.1 今回使用するパーツ一覧
パーツ名 | 説明 | 数 |
---|---|---|
PIC16F1829 | PIC本体 | 1 |
ソケット | PICをつけるソケット | 1 |
コンデンサ(0.1[μF]) | バイパスコンデンサ | 1 |
タクトスイッチ | ニュートラル、正転、逆転用 | 3 |
7セグメントディスプレイ(OSL40562) | 制御値の表示用(4桁表示) | 1 |
抵抗(1[kΩ]) | 7セグメントディスプレイ制御用 | 8 |
抵抗(4.7[kΩ]) | 7セグメントディスプレイ制御用 | 4 |
抵抗(10[kΩ]) | 7セグメントディスプレイ制御用 | 4 |
NPNトランジスタ(C1815) | 7セグメントディスプレイ制御用 | 4 |
電源(5[V]) | ラジコンサーボチェッカー動作用 | 1 |
電源 | ラジコンサーボ用 | 1 |
ラジコンサーボ | Tower Pro マイクロサーボ SG90 | 1 |
注1:今回使用している7セグメントディスプレイはカソードコモンタイプです。
注2:ラジコンサーボ用の電源は、実際に使用する電源を使用してください。
2.3.2 PICの配線
No. | PIC | 接続先 | 補足 |
---|---|---|---|
1 | VDD | 電源 | 5[V] |
2 | RA5 | タクトスイッチ | 逆転用 |
3 | RA4 | タクトスイッチ | ニュートラル用 |
4 | RA3 | タクトスイッチ | 正転用 |
5 | RC5 | -未使用- | |
6 | RC4 | -未使用- | |
7 | RC3 | トランジスタ(7セグ) | 表示切り替え用(1000の位) |
8 | RC6 | トランジスタ(7セグ) | 表示切り替え用(100の位) |
9 | RC7 | トランジスタ(7セグ) | 表示切り替え用(10の位) |
10 | RB7 | トランジスタ(7セグ) | 表示切り替え用(1の位) |
11 | RB6 | ラジコンサーボ | |
12 | RB5 | 7セグ(a) | |
13 | RB4 | 7セグ(b) | |
14 | RC2 | 7セグ(c) | |
15 | RC1 | 7セグ(d) | |
16 | RC0 | 7セグ(e) | |
17 | RA2 | 7セグ(f) | |
18 | RA1 | 7セグ(g) | |
19 | RA0 | 7セグ(dp) | |
20 | VSS | グランド |
2.3.3 回路の構造
PIC16F1829のピンはほとんど7セグメントディスプレイの表示用に使用しています。サーボの制御に1ピン、タクトスイッチに3ピン使用し、空きは2ピンとなっています。
7セグメントディスプレイに現在の制御値を表示、タクトスイッチを押すことで制御値を変更します。現在表示している制御値と同じ信号が、接続しているラジコンサーボに対して出力されます。
2.3.4 7セグメントディスプレイについて
今回使用している7セグメントディスプレイはカソードコモンタイプになっています。なので、表示桁切り替え用のトランジスタはグランドに接続します。トランジスタもアノードコモンとは違うので注意してください。
2.3.5 タクトスイッチ
タクトスイッチを押すと制御値の加算、減算またはニュートラル値の設定を行います。
2.3.6 ラジコンサーボの電源
ラジコンサーボの電源はPIC制御用の電源ではなく、実際に使用する電源を使用してください。
3.プログラム
プログラムの基本的な部分は以下の記事を参考にしてください。今回の説明では省略します。
3.1 注意事項
今回作成するラジコンサーボチェッカーでは、異常操作の対応を特に行っていません。なのでタクトスイッチを同時に押すなどのような使用は、おかしな動きになる場合があるので注意してください。
3.2 タクトスイッチの動作
タクトスイッチを1回押すと制御値が1だけ加算または減算します。長押しすると10ずつ変更するようにしています。ニュートラル値の設定ボタンは、押すとニュートラル値に変更します。
3.3 プログラムの説明
プログラムを見ながら以下の説明を見てください。ポイントを簡単に説明します。ソースコードは次の節にあるので、そちらを参照してください。
#define IO_SW_ON 0 #define IO_SW_OFF 1
スイッチ状態の定数を定義しています。
#define SEVEN_SEG_IO_ON 1 #define SEVEN_SEG_IO_OFF 0 #define SEVEN_SEG_SIZE 4
ラジコンサーボへの出力信号の定数を定義しています。
#define TMR1_OFFSET 25536
タイマ制御用の定数を定義しています。
#define NEUTRAL_PLS 1500 #define SERVO_PLS_MAX 3000 #define SERVO_PLS_MIN 100
ラジコンサーボ制御用の定数を定義しています。
この定数の値を使用するラジコンサーボに応じて変更してください。
#define SERVO_SKIP_CNT 1000 #define SERVO_DELAY_CNT 100
タクトスイッチを長押しした際の判断用の定数を定義しています。
#define SEG_LED_A RB5 #define SEG_LED_B RB4 #define SEG_LED_C RC2 #define SEG_LED_D RC1 #define SEG_LED_E RC0 #define SEG_LED_F RA2 #define SEG_LED_G RA1 #define SEG_LED_DP RA0 #define SEG_DEGI_1 RC3 // 1000の位 #define SEG_DEGI_2 RC6 // 100の位 #define SEG_DEGI_3 RC7 // 10の位 #define SEG_DEGI_4 RB7 // 1の位
7セグメントディスプレイ表示制御用ピン、および、桁制御用ピンの定数を定義しています。
#define SERVO_SW1 RA5 // PLS値を減算 #define SERVO_SW2 RA4 // PLS値をニュートラルへ #define SERVO_SW3 RA3 // PLS値を加算
タクトスイッチと接続しているピンの定数を定義しています。
#define SERVO_IO RB6
ラジコンサーボ制御用ピンの定数を定義しています。
const unsigned char seg_led[18] = { {0b00111111}, // 0 {0b00000110}, // 1 {0b01011011}, // 2 {0b01001111}, // 3 {0b01100110}, // 4 {0b01101101}, // 5 {0b01111101}, // 6 {0b00100111}, // 7 {0b01111111}, // 8 {0b01101111}, // 9 {0b00000001}, // a {0b00000010}, // b {0b00000100}, // c {0b00001000}, // d {0b00010000}, // e {0b00100000}, // f {0b01000000}, // g {0b10000000} // dp };
7セグメントディスプレイの表示用テーブルを定義しています。
volatile unsigned char seven_seg_data[ SEVEN_SEG_SIZE ] = {0};
7セグメントディスプレイ制御用のグローバル変数宣言しています。
volatile signed short servo_pls = NEUTRAL_PLS; volatile signed short work_servo_pls = NEUTRAL_PLS;
ラジコンサーボ制御用のグローバル変数宣言しています。
void seven_seg_ctrl( void ); void out_seven_seg(short , short );
関数のプロトタイプ宣言しています。
void interrupt isr_ctrl( void ) { // タイマ1割り込み処理 if( TMR1IF ) { SERVO_IO = 1; CCPR1 = work_servo_pls; TMR1 = TMR1_OFFSET; // 20msec毎に割り込み TMR1IF = 0; } // CCP1割り込み処理 if( CCP1IF ) { SERVO_IO = 0; CCP1IF = 0; } }
ラジコンサーボを制御するための割り込み処理をしています。詳しくは「ラジコンサーボを動かす」を参照してください。
bool now_sw[3] = {0}; bool old_sw[3] = {0}; bool skip_flg[3] = {0}; short skip_cnt[3] = {0}; short delay_cnt[3] = {0}; short wk; short i; OSCCON = 0b01110000 ; // 内部クロック8MHz OPTION_REG = 0b00000000 ; // プルアップ抵抗有効 ANSELA = 0b00000000 ; // すべてデジタルI/Oに割当てる TRISA = 0b00111000 ; // ピンは全て出力に割当てる(RA3は入力のみとなる) PORTA = 0b00000000 ; // 出力ピンの初期化(全てLOWにする) WPUA = 0b00111000 ; ANSELB = 0b00000000 ; // すべてデジタルI/Oに割当てる TRISB = 0b00000000 ; // RB5を入力,他は全て出力に割当てる PORTB = 0b00000000 ; // 出力ピンの初期化(全てLOWにする) ANSELC = 0b00000000 ; // すべてデジタルI/Oに割当てる TRISC = 0b00000000 ; // ピンは全て出力に割当てる PORTC = 0b00000000 ; // 出力ピンの初期化(全てLOWにする) CCP1CON = 0b00001010 ; // コンペアモード T1CON = 0b00100100 ; // 分周1/4 クロック同期有効 TMR1 = TMR1_OFFSET; work_servo_pls = TMR1_OFFSET + 3000; // 1.5msec TMR1IE = 1; // タイマ1割り込み有効 CCP1IE = 1; // コンペアマッチ割り込み有効 TMR1ON = 1; // タイマ1 開始 TMR1IF = 0; CCP1IF = 0; PEIE = 1; GIE = 1;
各種変数の宣言および、PICの初期設定を行っています。
// スイッチ状態の取得 if( SERVO_SW1 == IO_SW_ON ) now_sw[0] = true; else now_sw[0] = false; if( SERVO_SW2 == IO_SW_ON ) now_sw[1] = true; else now_sw[1] = false; if( SERVO_SW3 == IO_SW_ON ) now_sw[2] = true; else now_sw[2] = false;
スイッチの状態を取得しています。
188 ~ 261行目(長いのでソースは省略)
スイッチを押したのか、長く押しているのか、放したのかを確認し、状態により制御値を変更しています。
長押しの判断方法は次の通りです。メイン処理は1回の処理が約1[ms]になっています(7セグメントディスプレイ表示処理にて1[ms]のスリープ)。なので、一定回数(定数:SERVO_SKIP_CNT)メイン処理が行われることで、どれだけの間ボタンを押していたのかを判断しています。
1回押すと1加算または減算、長押しすると10ずつ加算または減算しています。
定数 | 意味 | 初期値 | 補足 |
SERVO_SKIP_CNT | 繰り返し回数 (長押しを判定用) |
1000 | 約1秒で長押しとする |
SERVO_DELAY_CNT | 長押し中に値を加算・減算するまでの回数 | 100 | 100[ms]毎に加算・減算する |
// 表示桁に分割 wk = servo_pls; seven_seg_data[0] = wk % 10; wk /= 10; seven_seg_data[1] = wk % 10; wk /= 10; seven_seg_data[2] = wk % 10; wk /= 10; seven_seg_data[3] = wk; // 7seg 表示制御 seven_seg_ctrl();
7セグメントディスプレイの表示処理をしています。
// usec->タイマ1用のカウンタ用に変換 work_servo_pls = (short)TMR1_OFFSET + (short)(servo_pls * 2);
色々な処理後(スイッチによる値の変更など)のラジコンサーボ制御値(servo_pls)をタイマ1で使用するために計算し値を設定しています。タイマ1の設定を1カウント0.5[μs]にしているため、同じ単位のカウントにするため2倍しています。
for(i=0; i<3; i++) old_sw[i] = now_sw[i];
現在のスイッチの状態を保存しています。
288 ~ 359行目(長いのでソースは省略)
7セグメントディスプレイの表示処理を行っています。1回処理を実行すると、1桁表示します。繰り返し処理を実行することで、4桁表示に対応しています。
362 ~ 432行目(長いのでソースは省略)
7セグメントディスプレイで1桁を表示する処理をしています。どの部分を点灯させるかを判断しています。
3.4 ソースコード
プログラムの全文を掲載します。
<注意>
ファイル名は必要に応じて変更し利用してください。
本サイトの注意事項を確認してください。
ソースコードや回路図などを使用する場合、上記注意とともに、自己責任でお願いします。
4.動作確認
- 電源を入れるとニュートラル信号を出力し、その信号位置にラジコンサーボが回転します
- ボタンを押すとニュートラルへの移動、正転または逆転します(押すボタンによる)
- ボタンを長く押すと、早く正転または逆転します(押すボタンによる)
- 7セグメントディスプレイに現在の制御値(ハイ信号を出力している時間[μs])を表示
<更新履歴>
版 | 更新日 | 変更内容 |
1 | 2015年8月24日 | 新規作成 |
2 | 2016年10月8日 | フォーマット変更 |