Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
- Committer:
- DiGengengen
- Date:
- 2020-11-22
- Revision:
- 3:2c2276646a5c
- Parent:
- 2:1ae5e25618e0
- Child:
- 4:ba166f7b2b8f
File content as of revision 3:2c2276646a5c:
#include "mbed.h"
#include "IWCMD.h"
/* 設定 */
const int kModuleID = 1; // コントロールモジュールのID(い今のところ1だけ)
// Servo pulsewidth MIN MID MAX
double Servo_1_pulthwidth_range[3] = {0.0010, 0.0015, 0.0020};
double Servo_2_pulthwidth_range[3] = {0.0010, 0.0015, 0.0020};
double Servo_3_pulthwidth_range[3] = {0.0010, 0.0015, 0.0020};
double Servo_4_pulthwidth_range[3] = {0.0010, 0.0015, 0.0020};
double Servo_5_pulthwidth_range[3] = {0.0010, 0.0015, 0.0020};
double Servo_6_pulthwidth_range[3] = {0.0010, 0.0015, 0.0020};
/* 時間設定 */
/* WAIT_TIME_PM_REPLY + WAIT_TIME_PC_CMD > WDT_PERIOD => 接続状態でもWDTが必ず発動.
* WDT_PERIOD/2 < WAIT_TIME_PM_REPLY + WAIT_TIME_PC_CMD < WDT_PERIOD => 1or2回接続確認に失敗するとWDTが発動.
* WDT_PERIOD/(N+1) < WAIT_TIME_PM_REPLY + WAIT_TIME_PC_CMD < WDT_PERIOD/N => N回以上接続確認に失敗するとWDTが発動するかも.
*/
const float WAIT_TIME_PM_REPLY = 0.2f; // PMの接続確認を待機する時間.xbeeの通信時間を考えて十分に長くとるべし.しかしこの時間はPCからの操作を受け付けないのでできるだけ短いほうが望ましい.
const float WAIT_TIME_PC_CMD = 3.0f; // PCからの命令を待機する時間.長いほうがより長い時間PCからのコマンドを受け付けるが,WDTの周期に注意.
/* ピン設定 */
Serial pc(USBTX, USBRX, 9600);
Serial xbee(PA_9, PA_10, 9600);
DigitalOut xbee_reset(PA_1);
DigitalOut led[] = {
DigitalOut(PB_1),
DigitalOut(PF_0),
DigitalOut(PF_1),
};
PwmOut Servo_1(PA_8);
// PwmOut Servo_2(PA_0); // us_tickerにてTIM2を利用中のため使用不可
DigitalOut Servo_2(PA_0);
PwmOut Servo_3(PA_6_ALT0);
PwmOut Servo_4(PA_3);
PwmOut Servo_5(PB_4);
PwmOut Servo_6(PA_7_ALT1);
/* タイマー設定 */
Timer tim;
Ticker s2_pwm_tick;
Timeout s2_pwm_timo;
/* グローバル変数 */
double s2_pulsewidth_curr = 0.0015;
/* プロトタイプ宣言 */
void pwm_init();
void xbee_init();
void PM_checkconnection(int);
void transmission_xbee2pc_wait_for(float);
void Servo_2_off();
void Servo_2_on();
void Servo_2_pwm_interrupt();
void Servo_2_period_ms(int);
void Servo_2_pulsewidth(double);
void cmd_exe_wait_for(float);
void cmd_exe(char);
void reset_all_motors();
Timer opt_tim;
/* メイン文 */
int main(){
// 初期化
pwm_init();
xbee_init();
wait(1);
led[0] = 1;
// ループ
while(1){
pc.printf("CM : %02d\n", kModuleID);
// PM1接続確認
PM_checkconnection(1); // PM1に接続確認
transmission_xbee2pc_wait_for(WAIT_TIME_PM_REPLY); // xbeeからの受信待機
// コマンド実行
cmd_exe_wait_for(WAIT_TIME_PC_CMD/2.0f); // PCからのコマンド待機
// PM2接続確認
PM_checkconnection(2); // PM2に接続確認
transmission_xbee2pc_wait_for(WAIT_TIME_PM_REPLY); // xbeeからの受信待機
// コマンド実行
cmd_exe_wait_for(WAIT_TIME_PC_CMD/2.0f); // PCからのコマンド待機
}
}
/* PWM初期化 */
void pwm_init(){
Servo_1.period_ms(20);
Servo_2_period_ms(20);
Servo_3.period_ms(20);
Servo_4.period_ms(20);
Servo_5.period_ms(20);
Servo_6.period_ms(20);
reset_all_motors();
}
/* xbee初期化 */
void xbee_init(){
xbee_reset = 1;
}
/* PMとの接続確認,PMのWDT更新 */
void PM_checkconnection(int id){
if(id == 1){
xbee.putc(IWCMD_PM1_CCO);
}else if(id == 2){
xbee.putc(IWCMD_PM2_CCO);
}
}
/* wait_time秒間,xbeeからの通信を受信してPCに表示 */
void transmission_xbee2pc_wait_for(float wait_time){
tim.reset();
tim.start();
while(tim.read() < wait_time){
if(xbee.readable()){
pc.putc(xbee.getc());
}
}
tim.stop();
}
/* wait_time秒間,PCからの通信を受信してコマンド実行 */
void cmd_exe_wait_for(float wait_time){
tim.reset();
tim.start();
while(tim.read() < wait_time){
if(pc.readable()){
cmd_exe(pc.getc());
}
}
tim.stop();
}
/*各コマンド実行内容*/
// 全てのモータを停止,初期位置に.
void reset_all_motors(){
Servo_1.pulsewidth(Servo_1_pulthwidth_range[1]);
Servo_2_pulsewidth(Servo_2_pulthwidth_range[1]);
Servo_3.pulsewidth(Servo_3_pulthwidth_range[1]);
Servo_4.pulsewidth(Servo_4_pulthwidth_range[1]);
Servo_5.pulsewidth(Servo_5_pulthwidth_range[1]);
Servo_6.pulsewidth(Servo_6_pulthwidth_range[1]);
xbee.putc(IWCMD_PM1_SPS);
xbee.putc(IWCMD_PM2_SPS);
}
/* Servo2用手動PWM */
void Servo_2_off(){
Servo_2 = 0;
}
void Servo_2_on(){
Servo_2 = 1;
s2_pwm_timo.attach(&Servo_2_off, s2_pulsewidth_curr);
}
void Servo_2_period_ms(int p_ms){
Servo_2_off();
s2_pwm_tick.attach(&Servo_2_on, (double)p_ms / 1.0e3);
}
void Servo_2_pulsewidth(double p){
s2_pulsewidth_curr = p;
}
//const int s2_division = 100; // PWM用分割数
//int s2_duty; // PWM用分割数のうちduty個分High出力
//int s2_period_us; // PWM用分割数1つあたりの周期
//
//void Servo_2_period_ms(int p_ms){
// s2_period_us = (p_ms*1000) / s2_division;
// s2_pwm_tick.attach_us(&Servo_2_pwm_interrupt, s2_period_us);
//}
//void Servo_2_pulsewidth(double pw){
// s2_duty = pw*1000000.0 / (double)s2_period_us;
//}
//void Servo_2_pwm_interrupt(){
// static int t = 0;
// if(t == s2_division){
// Servo_2 = 0;
// t = 0;
// return;
// }
// if(t == s2_division-s2_duty)
// Servo_2 = 1;
// t++;
//}
/* コマンド実行 */
void cmd_exe(char cmd){
switch(cmd){
case IWCMD_CM_SS1_PP: //スラスターサーボ1を正位置
Servo_1.pulsewidth(Servo_1_pulthwidth_range[2]);
break;
case IWCMD_CM_SS1_SP: //スラスターサーボ1を零位置
Servo_1.pulsewidth(Servo_1_pulthwidth_range[1]);
break;
case IWCMD_CM_SS1_NP: //スラスターサーボ1を負位置
Servo_1.pulsewidth(Servo_1_pulthwidth_range[0]);
break;
case IWCMD_CM_SS2_PP: //スラスターサーボ2を正位置
Servo_2_pulsewidth(Servo_2_pulthwidth_range[2]);
break;
case IWCMD_CM_SS2_SP: //スラスターサーボ2を零位置
Servo_2_pulsewidth(Servo_2_pulthwidth_range[1]);
break;
case IWCMD_CM_SS2_NP: //スラスターサーボ2を負位置
Servo_2_pulsewidth(Servo_2_pulthwidth_range[0]);
break;
case IWCMD_CM_SS3_PP: //スラスターサーボ3を正位置
Servo_3.pulsewidth(Servo_3_pulthwidth_range[2]);
break;
case IWCMD_CM_SS3_SP: //スラスターサーボ3を零位置
Servo_3.pulsewidth(Servo_3_pulthwidth_range[1]);
break;
case IWCMD_CM_SS3_NP: //スラスターサーボ3を負位置
Servo_3.pulsewidth(Servo_3_pulthwidth_range[0]);
break;
case IWCMD_CM_SS4_PP: //スラスターサーボ4を正位置
Servo_4.pulsewidth(Servo_4_pulthwidth_range[2]);
break;
case IWCMD_CM_SS4_SP: //スラスターサーボ4を零位置
Servo_4.pulsewidth(Servo_4_pulthwidth_range[1]);
break;
case IWCMD_CM_SS4_NP: //スラスターサーボ4を負位置
Servo_4.pulsewidth(Servo_4_pulthwidth_range[0]);
break;
case IWCMD_CM_SS5_PP: //スラスターサーボ5を正位置
Servo_5.pulsewidth(Servo_5_pulthwidth_range[2]);
break;
case IWCMD_CM_SS5_SP: //スラスターサーボ5を零位置
Servo_5.pulsewidth(Servo_5_pulthwidth_range[1]);
break;
case IWCMD_CM_SS5_NP: //スラスターサーボ5を負位置
Servo_5.pulsewidth(Servo_5_pulthwidth_range[0]);
break;
case IWCMD_CM_SS6_PP: //スラスターサーボ6を正位置
Servo_6.pulsewidth(Servo_6_pulthwidth_range[2]);
break;
case IWCMD_CM_SS6_SP: //スラスターサーボ6を零位置
Servo_6.pulsewidth(Servo_6_pulthwidth_range[1]);
break;
case IWCMD_CM_SS6_NP: //スラスターサーボ6を負位置
Servo_6.pulsewidth(Servo_6_pulthwidth_range[0]);
break;
case IWCMD_CM_PM1_FR: //PM1を正転(IWCMD_PM1_SUU)
xbee.putc(IWCMD_PM1_SUU);
break;
case IWCMD_CM_PM1_ST: //PM1を停止(IWCMD_PM1_SPS)
xbee.putc(IWCMD_PM1_SPS);
break;
case IWCMD_CM_PM2_FR: //PM2を正転(IWCMD_PM2_SUU)
xbee.putc(IWCMD_PM2_SUU);
break;
case IWCMD_CM_PM2_ST: //PM2を停止(IWCMD_PM2_SPS)
xbee.putc(IWCMD_PM2_SPS);
break;
default:
reset_all_motors();
break;
}
led[2] =~ led[2];
}