正月休みの工作
正月休みの工作でライントレーサを作ってみました。
ラインを外さないようにするため速度を落とす必要があり、また、センサーが2個でON/OFFな制御のためカクカクしているため、センサーの増設、比例制御の導入などで改善を行いたい。
材料
- Arduino UNO R4
- サンハヤト Arduino用ユニバーサルキバン(UB-ARD03-P)
- 5V昇圧DCDCコンバーター(秋月 K-13065)
- デュアルHブリッジモータードライブ(MX1508使用)
- 赤外線反射センサーモジュール
- タミヤ ダブルギヤボックス
- タミヤ ナロータイヤセット 58mm径
- タミヤ ボールキャスター
- 電池ボックス 単3×2本 リード線(秋月 P-17271)
- 電池ボックス 単4×3本 リード線(秋月 P-03195)
- トグルスイッチ(DPST or DPDT)
- 絶縁キャップ(ニチフ LP TIC-22-黒)
- 木の板(3.5mm厚)
- ボルト&ナット
ポイント
- Arduino UNO R4はPWM周波数を自由に設定したいこと、e2studioの使い方の勉強、将来的にはFreeRTOS化したいなどで、Arduinoとしては使用せず、ベアメタルプログラミングを行った(E2-Liteを使用して書き込み)
- 単4×3本を5V昇圧コンバータを使用してArduinoの5Vピンに供給
- 単3×2本を昇圧せずにモータードライバに供給
- ギアボックスのギア比は114.7:1(タイプC)
- 外乱光の影響を減らすため、センサーに絶縁キャップを流用したカバーを装着
- 重心をキャスター側に寄せる
- マイコンは電池ボックスの上に配置
ソースコード(抜粋)
※エラー処理は全く行っていない
while (1)
{
R_ADC_Read(&g_adc0_ctrl, ADC_CHANNEL_0, &adc0);
R_ADC_Read(&g_adc0_ctrl, ADC_CHANNEL_1, &adc1);
if (adc1 > L_THRESHOLD && adc0 > R_THRESHOLD) {
state=3;
} else if (adc1 > L_THRESHOLD) {
state=2;
} else if (adc0 > R_THRESHOLD) {
state=1;
}
} else {
state=3;
count++;
}
switch(state) {
case 0:
R_GPT_DutyCycleSet(&g_timer0_ctrl, 0, GPT_IO_PIN_GTIOCA);
R_GPT_DutyCycleSet(&g_timer0_ctrl, gpt0_pwm_counts, GPT_IO_PIN_GTIOCB);
R_GPT_DutyCycleSet(&g_timer1_ctrl, gpt1_pwm_counts, GPT_IO_PIN_GTIOCA);
R_GPT_DutyCycleSet(&g_timer1_ctrl, 0, GPT_IO_PIN_GTIOCB);
break;
case 1:
R_GPT_DutyCycleSet(&g_timer0_ctrl, 0, GPT_IO_PIN_GTIOCA);
R_GPT_DutyCycleSet(&g_timer0_ctrl, gpt0_pwm_counts, GPT_IO_PIN_GTIOCB);
R_GPT_DutyCycleSet(&g_timer1_ctrl, 0, GPT_IO_PIN_GTIOCA);
R_GPT_DutyCycleSet(&g_timer1_ctrl, gpt1_pwm_counts, GPT_IO_PIN_GTIOCB);
break;
case 2:
R_GPT_DutyCycleSet(&g_timer0_ctrl, gpt0_pwm_counts, GPT_IO_PIN_GTIOCA);
R_GPT_DutyCycleSet(&g_timer0_ctrl, 0, GPT_IO_PIN_GTIOCB);
R_GPT_DutyCycleSet(&g_timer1_ctrl, gpt1_pwm_counts, GPT_IO_PIN_GTIOCA);
R_GPT_DutyCycleSet(&g_timer1_ctrl, 0, GPT_IO_PIN_GTIOCB);
break;
case 3:
R_GPT_DutyCycleSet(&g_timer0_ctrl, 0, GPT_IO_PIN_GTIOCA);
R_GPT_DutyCycleSet(&g_timer0_ctrl, 0, GPT_IO_PIN_GTIOCB);
R_GPT_DutyCycleSet(&g_timer1_ctrl, 0, GPT_IO_PIN_GTIOCA);
R_GPT_DutyCycleSet(&g_timer1_ctrl, 0, GPT_IO_PIN_GTIOCB);
break;
default:
break;
}
/* Delay */
R_BSP_SoftwareDelay(delay, BSP_DELAY_UNITS_MILLISECONDS);
}