2018.08.06
1_main.cpp
- Committer:
- sayzyas
- Date:
- 2018-08-06
- Revision:
- 3:4a7dea2da5b5
- Parent:
- 2:aeff576d5013
File content as of revision 3:4a7dea2da5b5:
/**********************************************************
* Project: B2 (1F-1)
* Title: CrExp B2 Motor Ctrl Main
* Target: LPCXpresso824-Max
* or ( LPC800Max )
* Author: sayzyas
* Date(Latest update) 2015.06.17(Wed)
* --------------------------------------------------------
*
* LPCXpresso 824-MAX
* +---------USB---------+
* | |
* | |
* | |
* | |
* | | SCL P0_10 D15
* | ## ### ## | SDA P0_11 D14
* | # # # # # # | AVDD
* N/A | # # # # # | GND
* +3V3 | ## # # # | SCK P0_24 D13
* NRST | # # # # # | MISO P0_25 D12
* +3V3 | # # # # ###### | MOSI P0_26 D11 -> I/O Ex Bd
* +5V | ## ##### # | SSEL P0_15 D10 -> I/O Ex Bd
* GND | | P0_27 D9 -> I/O Ex Bd
* GND | | P0_13 D8 -> I/O Ex Bd
* N/A | | P0_17 D7
* | | P0_16 D6
* A0 P0_6 | | PWM P0_28 D5
* A1 P0_14 | | PWM P0_18 D4
* A2 P0_23 | | PWM P0_12 D3
* A3 P0_22 | | PWM P0_19 D2
* A4 P0_21 | | TX P0_4 D1 -> UART Tx
* A5 P0_20 | | RX P0_0 D0 -> UART Rx
* +---------------------+
*
***************************************/
/*
2016.02.06
Added Limit switch detect control in RoboteQ motor control task.
*/
#define ___CURRENT_CHECK___
#include "mbed.h"
#include "rtos.h"
#include "common.h"
// Hardware setting
Serial pc(USBTX, USBRX); // tx, rx
Serial sdc2130(P0_4, P0_0); // Communicate with RpboteQ Driver by tx, rx
/* #### Don't use #### */
/* LED indicator for motor current indicate */
//DigitalOut myled0(P0_6); // My LED0
//DigitalOut myled1(P0_14); // My LED1
DigitalOut myled2(P0_23); // My LED2
DigitalOut myled3(P0_22); // My LED3
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
/* Analog input setting */
AnalogIn motor1_speed_adjin(A0);
AnalogIn motor2_speed_adjin(A1);
AnalogIn motor1_current_in(A5);
AnalogIn motor2_current_in(A4);
/* Digital In */
//DigitalIn limit_sw_rf(P0_24); // Limit switch (RF-h) for Transform controller only
//DigitalIn limit_sw_lb(P0_25); // Limit switch (LB-I) for Transform controller only
//2016.05.18 Limit switch input port change to opposite.
DigitalIn limit_sw_rf(P0_25); // Limit switch (RF-h) for Transform controller only
DigitalIn limit_sw_lb(P0_24); // Limit switch (LB-I) for Transform controller only
Mutex stdio_mutex;
bool flg_lsw_valid = false;
/* ** Worning *****************************
* M1 side is not compatible with Arduino IO
* exp board, so use following pin and modify
* or re-connect signal of IO exp board. */
//DigitalOut motor1_dir(P0_24); //D8
//PwmOut motor1_out(P0_25);
//DigitalOut motor1_out(P0_25); //D9
// M2 side is compatible with Arduino IO exp board.
//DigitalOut motor2_out(P0_15); //D10
//DigitalOut motor2_dir(P0_26); //D11
//PwmOut motor2_out(P0_15);
I2CSlave slave(P0_11, P0_10); //I2C SDA SCL
//QEI wheel( P0_15, P0_26, NC, ROTATE_PER_RESOLUTION, QEI::X2_ENCODING );
// ----------------------------------------------------------------
// Prototype
//
void led_onoff(void);
void led_demo(void);
void myled_control( int action );
int read_motor_current( uint32_t motor_no );
void current_read_task(void const *);
void motor1_ctrl( uint32_t onoff, uint32_t dir );
void motor2_ctrl( uint32_t onoff, uint32_t dir );
void RoboteQM1DrvCtrl_task( void const *);
void RoboteQM2DrvCtrl_task( void const *);
void motor_control_task(void const *);
void set_init_motor_current(uint32_t motor_no, float motor_current, int cnt);
float calb_motor_current(uint32_t motor_no, float motor_current);
// ----------------------------------------------------------------
// Sub Routine
//
void led_onoff(){
led1 = 1;
wait(0.5);
led1 = 0; // off
wait(0.5);
}
// LED demo
void led_demo(){
int i;
for( i = 0; i < 5; i++ ) {
led1 = LED_ON;
led2 = LED_OFF;
led3 = LED_OFF;
wait_ms(50);
led1 = LED_OFF;
led2 = LED_OFF;
led3 = LED_OFF;
wait_ms(50);
led1 = LED_OFF;
led2 = LED_ON;
led3 = LED_OFF;
wait_ms(50);
led1 = LED_OFF;
led2 = LED_OFF;
led3 = LED_OFF;
wait_ms(50);
led1 = LED_OFF;
led2 = LED_OFF;
led3 = LED_ON;
wait_ms(50);
led1 = LED_OFF;
led2 = LED_OFF;
led3 = LED_OFF;
wait_ms(50);
}
wait_ms(3000);
}
void myled_control( int action ){
for( int i = 0; i < 10; i++ ){
// myled0 = 1;
// myled1 = 1;
myled2 = 1;
myled3 = 1;
wait(0.2);
// myled0 = 0; // off
// myled1 = 0; // off
myled2 = 0; // off
myled3 = 0; // off
wait(0.2);
}
}
uint32_t motor1_lock_count = 0;
uint32_t motor2_lock_count = 0;
volatile bool flg_motor1_lockcup = false;
volatile bool flg_motor2_lockcup = false;
volatile uint32_t flg_motor1_lock = 0;
volatile uint32_t flg_motor2_lock = 0;
int i2c_saddress = 0;
uint8_t send_data[7];
float motor1_current_center_value;
float motor2_current_center_value;
float motor3_current_center_value;
uint8_t motor1_speed;
uint8_t motor2_speed;
uint16_t motor1_speed_adjdata;
uint16_t motor2_speed_adjdata;
// --------------------------------------------------------------
// Motor Current Calibration Function
// Arg: Motor Number 1 - 3
// --------------------------------------------------------------
void set_init_motor_current(uint32_t motor_no, float motor_current, int cnt){
for( int i = 0; i < cnt; i++ ){
if( motor_no == 1 ){
motor1_current_center_value = motor_current;
}
else if( motor_no == 2 ){
motor2_current_center_value = motor_current;
}
else if( motor_no == 3 ){
motor2_current_center_value = motor_current;
}
}
}
// --------------------------------------------------------------
// Motor Current Calibration Function
// Arg: Motor Number 1 - 3
// --------------------------------------------------------------
float calb_motor_current(uint32_t motor_no, float motor_current){
float rts;
if( motor_no == 1 ){
motor1_current_center_value += motor_current;
motor1_current_center_value /= 2;
rts = motor1_current_center_value;
}
else if( motor_no == 2 ){
motor2_current_center_value += motor_current;
motor2_current_center_value /= 2;
rts = motor2_current_center_value;
}
else if( motor_no == 3 ){
motor3_current_center_value += motor_current;
motor3_current_center_value /= 2;
rts = motor3_current_center_value;
}
else rts = 0;
return rts;
}
float motor1_current_fwd_thd;
float motor1_current_rvs_thd;
float motor2_current_fwd_thd;
float motor2_current_rvs_thd;
// --------------------------------------------------------------
// Motor Current Read Function
// Arg: Motor Number 1 - 3
// --------------------------------------------------------------
int read_motor_current( char motor_no, char motor_dir ){
float motor_current;
int i;
int mc_abs_pct = 0;
int mc_Threshold = 0;
if (motor_no == MOTOR_1 ){
motor_current = motor1_current_in.read()*100.0f;
mc_abs_pct = abs((int)((motor_current - motor1_current_center_value)*100.0f));
DEBUG_DSPMCNT("Bd1> M1:%lf/%lf= [%03d%%] th:%3.2f< <%3.2f\t", motor_current, motor1_current_center_value, mc_abs_pct, motor1_current_rvs_thd, motor1_current_fwd_thd );
// DEBUG_DSPMCNT("Bd1> M1 motor_current center value : %lf%%\r\n", motor1_current_center_value );
// DEBUG_DSPMCNT("Bd1> M1 motor_current abs percentage : %d%%\r\n", mc_abs_pct );
for( i = 0; i < (mc_abs_pct/10); i++){
DEBUG_DSPMCNT(">");
}
DEBUG_DSPMCNT("\r\n");
if( motor_dir == MOTOR_FWD ){
mc_Threshold = (int)motor1_current_fwd_thd;
DEBUG_PRINT_L1("Bd1> Upper threshold: %d\r\n", mc_Threshold);
}
else{
mc_Threshold = (int)motor1_current_rvs_thd;
DEBUG_PRINT_L1("Bd1> Lower threshold: %d\r\n", mc_Threshold);
}
if( mc_abs_pct > mc_Threshold ){
DEBUG_PRINT_L1("Bd1> **** MC1 Over the Limit [%d] ****\r\n", motor1_lock_count );
motor1_lock_count += 1;
if( motor1_lock_count >= MC_LOCK_COUNT ){
stdio_mutex.lock(); // Mutex Lock
flg_motor1_lock = 1;
stdio_mutex.unlock(); // Mutex Release
DEBUG_DSPMCNT("Bd1> #### MOTOR1 LOCK ! #### (%d)\r\n", flg_motor1_lock);
}
}
else{
DEBUG_PRINT_L1("Bd1> Pass\r\n");
if( motor1_lock_count > 0 ) motor1_lock_count -= 1;
else motor1_lock_count = 0;
}
}
else if (motor_no == MOTOR_2 ){
motor_current = motor2_current_in.read()*100.0f;
mc_abs_pct = abs((int)((motor_current - motor2_current_center_value)*100.0f));
DEBUG_DSPMCNT("Bd1> M2:%lf/%lf= [%03d%%] th:%3.2f< <%3.2f\t", motor_current, motor2_current_center_value, mc_abs_pct, motor2_current_rvs_thd, motor2_current_fwd_thd );
for( i = 0; i < (mc_abs_pct/10); i++){
DEBUG_DSPMCNT("=");
}
DEBUG_DSPMCNT("\r\n");
if( motor_dir == MOTOR_FWD ){
mc_Threshold = (int)motor2_current_fwd_thd;
}
else{
mc_Threshold = (int)motor2_current_rvs_thd;
}
if( mc_abs_pct > mc_Threshold ){
DEBUG_PRINT_L1("Bd1> **** MC2 Over the Limit [%d] ****\r\n", motor2_lock_count );
motor2_lock_count += 1;
if( motor2_lock_count >= MC_LOCK_COUNT ){
stdio_mutex.lock(); // Mutex Lock
flg_motor2_lock = 1;
stdio_mutex.unlock(); // Mutex Release
DEBUG_DSPMCNT("Bd1> #### MOTOR2 LOCK ! #### (%d)\r\n", flg_motor2_lock);
}
}
else{
if( motor2_lock_count > 0 ) motor2_lock_count -= 1;
else motor2_lock_count = 0;
}
}
return mc_abs_pct;
}
Timer t;
uint8_t motor_control_flag1 = 0x00;
uint8_t motor_control_flag2 = 0x00;
// --------------------------------------------------------------------------
// Motor Control Function
// Motor on off by microcontroller
// motor1_out : motor 1 on /off
// motor1_dir : motor 1 direction
// motor2_out : motor 2 on / off
// motor2_dir : motor 2 direction
// --------------------------------------------------------------------------
// "motor_control_flag" bit function
// bit
// ------
// 7 : motor number : upper nibble
// 6 : 0 : no motor
// 5 : 0 - 15 : motor number
// 4 :
// ------
// 3 : motor on/off, 0=off 1=on
// 2 :
// 1 :
// 0 : motor direction, 0=fwd 1=rev
void motor1_ctrl(
uint32_t onoff, // Motor ON/OFF
uint32_t dir // Motor rotation direction
){
// DEBUG_PRINT( "Motor No.%02d, [onoff:%d], [dir:%d]\r\n", motor_no, onoff, dir );
led1 = !onoff;
motor_control_flag1 &= 0x0F;
motor_control_flag1 |= 0x10;
if( dir == FLG_MOTOR_DIR_FWD ){
// motor1_dir = 0; // 0:Fwd, 1:Rvs
motor_control_flag1 &= 0xFE;
}
else if( dir == FLG_MOTOR_DIR_RVS ){
// motor1_dir = 1; // 0:Fwd, 1:Rvs
motor_control_flag1 |= 0x01;
}
// stdio_mutex.lock(); // Mutex Lock
if(( !flg_motor1_lock )&&( onoff )){ // Case of motor unlock by timer
// motor1_out = 1; // Motor1 on
motor_control_flag1 |= 0x08;
}
else{
// motor1_out = 0; // Motor1 off
motor_control_flag1 &= 0xF7;
}
// stdio_mutex.unlock(); // Mutex Release
}
void motor2_ctrl(
uint32_t onoff, // Motor ON/OFF
uint32_t dir // Motor rotaion direction
){
// DEBUG_PRINT( "Motor No.%02d, [onoff:%d], [dir:%d]\r\n", motor_no, onoff, dir );
led1 = !onoff;
motor_control_flag2 &= 0x0F;
motor_control_flag2 |= 0x20;
if( dir == FLG_MOTOR_DIR_FWD ){
// motor2_dir = 0; // 0:Fwd, 1:Rvs
motor_control_flag2 &= 0xFE;
}
else if( dir == FLG_MOTOR_DIR_RVS ){
// motor2_dir = 1; // 0:Fwd, 1:Rvs
motor_control_flag2 |= 0x01;
}
// stdio_mutex.lock(); // Mutex Lock
if(( !flg_motor2_lock )&&( onoff )){ // Case of motor unlock by timer
// motor2_out = 1; // Motor2 on
motor_control_flag2 |= 0x08;
}
else{
// motor2_out = 0; // Motor2 off
motor_control_flag2 &= 0xF7;
}
// stdio_mutex.unlock(); // Mutex Release
}
int limitSw_Sts = 0;
// -----------------------------------------------------
// Motor COntrol Task: loop forever !
// For RoboteQ motor controller
// Note. Motor control command should always send to
// RoboteQ controllet, so following should be
// done by thread.
// -----------------------------------------------------
// motor_control_flag bit function
// bit
// ------
// 7 : motor number : upper nibble
// 6 : 0 : no motor
// 5 : 0 - 15 : motor number
// 4 :
// ------
// 3 : motor on/off, 0=off 1=on
// 2 :
// 1 :
// 0 : motor direction, 0=fwd 1=rev
void RoboteQM1DrvCtrl_task( void const *){
while(1){
if( flg_motor1_lock ){
DEBUG_PRINT_L1("Bd1> M1 LOCK\r\n");
sdc2130.printf( "!G 1 0\r" ); // Motor off
}
else{
// DEBUG_PRINT("Motor Speed : %d\r\n", motor1_speed);
if(( motor_control_flag1 & 0x08 )){ // motor on
if(!(motor_control_flag1 & 0x01)){ // motor dir fwd
if((motor_control_flag1 & 0xF0) == 0x10){ // motor 1
DEBUG_PRINT_L1("Bd1> RoboteQ <-- M1 FWD (%d)\r\n", motor1_speed );
stdio_mutex.lock(); // Mutex Lock
// sdc2130.printf( "!AC 1 10000" );
sdc2130.printf( "!G 1 %d\r", motor1_speed*10 ); // Motor on reverse 100.0%
// sdc2130.printf( "!G 1 %d\r", motor1_speed*10 ); // Motor on reverse 100.0%
limitSw_Sts &= 0xFE;
stdio_mutex.unlock(); // Mutex Lock
}
}
else{ // motor dir rev
if((motor_control_flag1 & 0xF0) == 0x10){ // motor 1
stdio_mutex.lock(); // Mutex Lock
if(( limit_sw_rf == 0 )&&(flg_lsw_valid == true )){
DEBUG_PRINT_L1("Limit switch ON (M1 reverse) \r\n");
DEBUG_PRINT_L4("Bd1> RoboteQ <-- M1 RVS (0)\r\n");
sdc2130.printf("!G 1 0\r"); // Motor off
limitSw_Sts |= 0x01;
}
else{
DEBUG_PRINT_L1("Bd1> RoboteQ <-- M1 RVS (%d)\r\n", motor1_speed*-1 );
sdc2130.printf( "!G 1 %d\r", (motor1_speed*-1)*10 ); // Motor on reverse 100.0%
limitSw_Sts &= 0xFE;
}
stdio_mutex.unlock(); // Mutex Lock
}
}
}
else{
// DEBUG_PRINT_L1("Bd1> M1 OFF\r\n");
sdc2130.printf( "!G 1 0\r" ); // Motor off
// Thread::wait(30);
// calb_motor_current(1, motor1_current_in.read()*100.0f);
}
}
Thread::wait(7);
}
}
void RoboteQM2DrvCtrl_task( void const *){
while(1){
if( flg_motor2_lock ){
DEBUG_PRINT_L1("Bd1> M2 LOCK\r\n");
sdc2130.printf( "!G 2 0\r" ); // Motor off
}
else{
// DEBUG_PRINT("Motor Speed : %d\r\n", motor1_speed);
if(( motor_control_flag2 & 0x08 )){ // motor on
if(!(motor_control_flag2 & 0x01)){ // motor dir fwd
if((motor_control_flag2 & 0xF0) == 0x20){ // motor 2
DEBUG_PRINT_L1("Bd1> RoboteQ <-- M2 FWD (%d)\r\n", motor2_speed );
// sdc2130.printf( "!G 2 1000\r" ); // Motor on reverse 100.0%
stdio_mutex.lock(); // Mutex Lock
sdc2130.printf( "!G 2 %d\r", motor2_speed*10 ); // Motor on reverse 100.0%
// sdc2130.printf( "!G 2 %d\r", motor2_speed*10 ); // Motor on reverse 100.0%
limitSw_Sts &= 0xFD;
stdio_mutex.unlock(); // Mutex Lock
}
}
else{ // motor dir rev
if((motor_control_flag2 & 0xF0) == 0x20){ // motor 2
// sdc2130.printf( "!G 2 -1000\r" ); // Motor on reverse 100.0%
stdio_mutex.lock(); // Mutex Lock
if(( limit_sw_lb == 0 )&&(flg_lsw_valid == true )){
DEBUG_PRINT_L1("Limit switch ON (M2 reverse) \r\n");
DEBUG_PRINT_L4("Bd1> RoboteQ <-- M2 RVS (0)\r\n");
sdc2130.printf("!G 2 0\r"); // Motor off
limitSw_Sts |= 0x02;
}
else{
DEBUG_PRINT_L1("Bd1> RoboteQ <-- M2 RVS (%d)\r\n", motor2_speed*-1);
sdc2130.printf("!G 2 %d\r", (motor2_speed*-1)*10); // Motor on reverse 100.0%
limitSw_Sts &= 0xFD;
}
stdio_mutex.unlock(); // Mutex Lock
}
}
}
else{
// DEBUG_PRINT_L1("Bd1> M2 OFF\r\n");
sdc2130.printf( "!G 2 0\r" ); // Motor off
// Thread::wait(30);
// calb_motor_current(2, motor2_current_in.read()*100.0f);
}
}
Thread::wait(1);
}
}
int motor1_current_pct;
int motor2_current_pct;
// ========================================================================
// Thread: Motor Control Task
// ========================================================================
void motor_control_task(void const *) {
char buf[14]; // command buffer
char res_msg2[6];
slave.address(i2c_saddress);
/*
* I2C Access
*/
while(1) {
int i = slave.receive();
slave.read(buf, NumberOfI2CCommand);
// DEBUG_PRINT_L3("Bd1> Slave Received\r\n");
switch (i) {
case I2CSlave::NoData:
// DEBUG_PRINT_L3("Bd1> NoData(the slave has not been addressed)\r\n");
// motor_current_pct = read_motor_current(2);
break;
case I2CSlave::ReadAddressed:
// Send Motor Current here to host controller.
res_msg2[0] = (char)(motor1_current_pct & 0xFF);
res_msg2[1] = (char)(motor2_current_pct & 0xFF);
res_msg2[3] = (char)(limitSw_Sts);
if( flg_motor1_lockcup == true ){
res_msg2[4] = '1'; // Motor 1 Lock !!
}
else if( flg_motor2_lockcup == true ){
res_msg2[4] = '2'; // Motor 2 Lock !!
}
else{
res_msg2[4] = 'S';
}
res_msg2[5] = '\0';
DEBUG_PRINT_L3("\t\t motor1_current_pct = %d\r\n", motor1_current_pct );
DEBUG_PRINT_L3("\t\t motor2_current_pct = %d\r\n", motor2_current_pct );
DEBUG_PRINT_L3("\t\t imit sw = 0x%02x\r\n", limitSw_Sts );
if( flg_motor1_lockcup == true ){
res_msg2[2] = 0x88;
DEBUG_PRINT_L3(" 0: [%d]\r\n", res_msg2[0] );
DEBUG_PRINT_L3(" 1: [%d]\r\n", res_msg2[1] );
DEBUG_PRINT_L3(" 2: [0x%02x]\r\n", res_msg2[2] );
DEBUG_PRINT_L3(" 3: [%d]\r\n", res_msg2[3] );
DEBUG_PRINT_L3(" 4: [%c]\r\n", res_msg2[4] );
}
else{
res_msg2[2] = 0x00;
}
slave.write(res_msg2, 6); // Includes null char
break;
case I2CSlave::WriteGeneral:
// DEBUG_PRINT_L3("Bd1> the master is writing to all slave\r\n");
slave.read(buf, NumberOfI2CCommand);
// DEBUG_PRINT_L3("Bd1> Read G: %s\r\n", buf);
break;
case I2CSlave::WriteAddressed:
motor1_current_fwd_thd = (float)(((buf[I2C_CP_M1_FWD_CNTTH_U]<<8)&0xFF00)|(buf[I2C_CP_M1_FWD_CNTTH_L]&0xFF)); // <-- New!
motor1_current_rvs_thd = (float)(((buf[I2C_CP_M1_RVS_CNTTH_U]<<8)&0xFF00)|(buf[I2C_CP_M1_RVS_CNTTH_L]&0xFF)); // <-- New!
motor2_current_fwd_thd = (float)(((buf[I2C_CP_M2_FWD_CNTTH_U]<<8)&0xFF00)|(buf[I2C_CP_M2_FWD_CNTTH_L]&0xFF)); // <-- New!
motor2_current_rvs_thd = (float)(((buf[I2C_CP_M2_RVS_CNTTH_U]<<8)&0xFF00)|(buf[I2C_CP_M2_RVS_CNTTH_L]&0xFF)); // <-- New!
// Set Motor Speed here: Speed is set by Main Controller via I2C command right now.
// In case of Winch motor controller, Speed is set by analog data from A0 and A1 <-- It's for evaluation
// for devalopment the "Fix position falling winch".
if( buf[I2C_CP_M1_DIR] == MOTOR_STP )
{
motor1_speed = 0;
}
else
{
if(( buf[I2C_CP_M1_DIR] == MOTOR_FWD )||( buf[I2C_CP_M1_DIR] == MOTOR_RVS ))
{
motor1_speed = buf[I2C_CP_M1_SPEED];
}
}
if( buf[I2C_CP_M2_DIR] == MOTOR_STP )
{
motor2_speed = 0;
}
else
{
if(( buf[I2C_CP_M2_DIR] == MOTOR_FWD )||( buf[I2C_CP_M2_DIR] == MOTOR_RVS ))
{
motor2_speed = buf[I2C_CP_M2_SPEED];
}
}
// DEBUG_PRINT_L1( "Bd1> GOT MOTOR SPEED: M1[ %d ] ", motor1_speed );
// DEBUG_PRINT_L1( "M2[ %d ] \r\n", motor2_speed );
if( buf[I2C_CP_COMMAND] == 'V' ){
flg_lsw_valid = true;
}
else{
flg_lsw_valid = false;
}
if( buf[I2C_CP_M2_DIR] == MOTOR_STP ){
//DEBUG_PRINT_L1("M2 Off_1\r\n");
motor2_ctrl( FLG_MOTOR_OFF, FLG_MOTOR_DIR_NONE );
t.stop();
motor2_lock_count = 0;
motor2_current_pct = 0;
flg_motor2_lockcup = false;
stdio_mutex.lock();
flg_motor2_lock = 0;
stdio_mutex.unlock();
}
else if(( buf[I2C_CP_M2_DIR] == MOTOR_FWD )&&(flg_motor2_lockcup == false)){ // MOTOR2 FORWARD
motor2_ctrl( FLG_MOTOR_ON, FLG_MOTOR_DIR_FWD );
motor2_current_pct = read_motor_current( MOTOR_2, MOTOR_FWD );
}
else if(( buf[I2C_CP_M2_DIR] == MOTOR_RVS )&&(flg_motor2_lockcup == false)){ // MOTOR2 REVERSE
motor2_ctrl( FLG_MOTOR_ON, FLG_MOTOR_DIR_RVS );
motor2_current_pct = read_motor_current( MOTOR_2, MOTOR_RVS );
}
// 2016.11.07: following section commented out ! :
// If this section is velidate, then suddnly motor stopped because motor on
// flag is cleared. this is bug !!
/*
else{
//DEBUG_PRINT_L1("M2 Off_2\r\n");
motor2_ctrl( FLG_MOTOR_OFF, FLG_MOTOR_DIR_NONE );
motor2_lock_count = 0;
motor2_current_pct = 0;
t.stop();
stdio_mutex.lock();
flg_motor2_lock = 0;
stdio_mutex.unlock();
}
*/
if( buf[I2C_CP_M1_DIR] == MOTOR_STP ){
//DEBUG_PRINT_L1("M1 Off_1\r\n");
motor1_ctrl( FLG_MOTOR_OFF, FLG_MOTOR_DIR_NONE );
t.stop();
motor1_current_pct = 0;
motor1_lock_count = 0;
flg_motor1_lockcup = false;
stdio_mutex.lock();
flg_motor1_lock = 0;
stdio_mutex.unlock();
}
else if(( buf[I2C_CP_M1_DIR] == MOTOR_FWD)&&(flg_motor1_lockcup == false)){ // MOTOR1 FORWARD
motor1_ctrl( FLG_MOTOR_ON, FLG_MOTOR_DIR_FWD );
motor1_current_pct = read_motor_current( MOTOR_1, MOTOR_FWD );
}
else if(( buf[I2C_CP_M1_DIR] == MOTOR_RVS )&&(flg_motor1_lockcup == false)){ // MOTOR1 REVERSE
motor1_ctrl( FLG_MOTOR_ON, FLG_MOTOR_DIR_RVS );
motor1_current_pct = read_motor_current( MOTOR_1, MOTOR_RVS );
}
// 2016.11.07: following section commented out ! :
// If this section is velidate, then suddnly motor stopped because motor on
// flag is cleared. this is bug !!
/* else{
motor1_ctrl( FLG_MOTOR_OFF, FLG_MOTOR_DIR_NONE );
motor1_current_pct = 0;
motor1_lock_count = 0;
t.stop();
stdio_mutex.lock();
// pc.printf("%%%%%%%%\r\n");
flg_motor1_lock = 0;
stdio_mutex.unlock();
}
*/
break;
}
for(int i = 0; i < NumberOfI2CCommand; i++) buf[i] = 0; // Clear buffer
stdio_mutex.lock();
#ifdef __SEPARATE_TYPR__
if ( flg_motor1_lock == 1 ){
t.start();
DEBUG_PRINT_L1( "Bd1> MOTOR1 lock time start\r\n" );
if( t.read_ms() > 100 ){ // 1sec
DEBUG_PRINT_L1("Bd1> MOTOR1 STOP lock with time up: %d \r\n", flg_motor1_lock );
// DEBUG_PRINT_L1("Bd1> MOTOR2 STOP lock with time up: %d \r\n", flg_motor2_lock );
motor1_ctrl( FLG_MOTOR_OFF, FLG_MOTOR_DIR_NONE );
// motor2_ctrl( FLG_MOTOR_OFF, FLG_MOTOR_DIR_NONE );
flg_motor1_lockcup = true;
// flg_motor2_lockcup = true;
t.stop();
}
}
if ( flg_motor2_lock == 1 ){
t.start();
DEBUG_PRINT_L1( "Bd1> MOTOR2 lock time start\r\n" );
if( t.read_ms() > 100 ){ // 1sec
// DEBUG_PRINT_L1("Bd1> MOTOR1 STOP lock with time up: %d \r\n", flg_motor1_lock );
DEBUG_PRINT_L1("Bd1> MOTOR2 STOP lock with time up: %d \r\n", flg_motor2_lock );
// motor1_ctrl( FLG_MOTOR_OFF, FLG_MOTOR_DIR_NONE );
motor2_ctrl( FLG_MOTOR_OFF, FLG_MOTOR_DIR_NONE );
// flg_motor1_lockcup = true;
flg_motor2_lockcup = true;
t.stop();
}
}
#else
/*
Motor Lock detection and flag on part
-------------------------------------
Currently, in case of each motor lock, then both motor will stop
and both flag on.
Therefore, PC S/W can detect motor lock only if only one side flag check.
*/
if (( flg_motor1_lock == 1 )||( flg_motor2_lock == 1 )){
t.start();
DEBUG_PRINT_L1( "Bd1> MOTOR2 lock time start\r\n" );
if( t.read_ms() > 100 ){ // 1sec
DEBUG_PRINT_L1("Bd1> MOTOR1 STOP lock with time up: %d \r\n", flg_motor1_lock );
DEBUG_PRINT_L1("Bd1> MOTOR2 STOP lock with time up: %d \r\n", flg_motor2_lock );
motor1_ctrl( FLG_MOTOR_OFF, FLG_MOTOR_DIR_NONE );
motor2_ctrl( FLG_MOTOR_OFF, FLG_MOTOR_DIR_NONE );
flg_motor1_lockcup = true;
flg_motor2_lockcup = true;
t.stop();
}
}
#endif
stdio_mutex.unlock();
// calb_motor_current(1, motor1_current_in.read()*100.0f);
// calb_motor_current(2, motor2_current_in.read()*100.0f);
Thread::wait(1);
}
}
// Data recieve and display
void callback() {
char c;
// Note: you need to actually read from the serial to clear the RX interrup
c = sdc2130.getc();
// if( c != '+')
// DEBUG_PRINT_L1("%c\r\n", c);
// DEBUG_PRINT("%c\r\n", sdc2130.getc()); // <-- may be this is correct ???
}
int main() {
int32_t counter = 0;
pc.baud(115200);
sdc2130.baud(115200);
limit_sw_rf.mode( PullUp ); // use internal pullup
limit_sw_lb.mode( PullUp ); // use internal pullup
DEBUG_PRINT_L0("\r\n");
DEBUG_PRINT_L0("Bd1> +--------------------------------------------------------------\r\n");
DEBUG_PRINT_L0("Bd1> | Project: B2 Crawler Explorer for 1F-1 PCV internal inspection\r\n");
DEBUG_PRINT_L0("Bd1> |---------\r\n");
DEBUG_PRINT_L0("Bd1> | This is: Each Motor Controller of Main Controller\r\n");
DEBUG_PRINT_L0("Bd1> | Letest update: %s\r\n", LatestUpDate);
DEBUG_PRINT_L0("Bd1> | Program Revision: %s\r\n", ProgramRevision);
DEBUG_PRINT_L0("Bd1> | Author: %s\r\n", Author);
DEBUG_PRINT_L0("Bd1> | Copyright(C) 2015 %s Allright Reserved\r\n", Company);
DEBUG_PRINT_L0("Bd1> | -------------------------------------------------\r\n");
DEBUG_PRINT_L0("Bd1> | RoboteQ motor control thread added\r\n");
DEBUG_PRINT_L0("Bd1> | 2016.03.16 Limit switch control added\r\n");
DEBUG_PRINT_L0("Bd1> +--------------------------------------------------------------\r\n");
DEBUG_PRINT_L0("Bd1> \r\ninitializing ... \r\n");
// All output off
// motor1_out = 0;
// motor2_out = 0;
i2c_saddress = I2C_ADDRESS_WINCH; // 0x10
//i2c_saddress = I2C_ADDRESS_TRANSFORM; // 0x08
//i2c_saddress = I2C_ADDRESS_CRAWLER; // 0x04
sdc2130.attach(&callback);
sdc2130.printf( "^ECHOF 1\r" );
sdc2130.printf( "^ECHOF 2\r" );
led_demo();
DEBUG_PRINT_L0("Bd1> > Board type: 0x%02x\r\n",i2c_saddress );
// Set the initial value of motor current
DEBUG_PRINT_L0("\r\nBd1> Read and set the initial value of motor current ... \r\n");
set_init_motor_current(1, motor1_current_in.read()*100.0f, 1000);
set_init_motor_current(2, motor2_current_in.read()*100.0f, 1000);
DEBUG_PRINT_L0( "Bd1> *****************************************\r\n" );
DEBUG_PRINT_L0( "Bd1> Init motor current1: %3.4f%\r\n", motor1_current_center_value );
DEBUG_PRINT_L0( "Bd1> Init motor current2: %3.4f%\r\n", motor2_current_center_value );
DEBUG_PRINT_L0( "Bd1> *****************************************\r\n" );
// Thread (
// void(*task)(void const *argument),
// void *argument=NULL,
// osPriority priority=osPriorityNormal,
// uint32_t stack_size=DEFAULT_STACK_SIZE,
// unsigned char *stack_pointer=NULL
//)
// -----------------------------------------------------------------
// In case of multi stack using , should increase stack size.
// 2016.04.07
// -----------------------------------------------------------------
DEBUG_PRINT_L0("Bd1> Start RoboteQ motor driver task ... \r\n");
Thread motorDrvControlTask1(RoboteQM1DrvCtrl_task, NULL, osPriorityNormal, 1024);
Thread motorDrvControlTask2(RoboteQM2DrvCtrl_task, NULL, osPriorityNormal, 1024); //
DEBUG_PRINT_L0("Bd1> Start motor control taslk (main thread) ... \r\n");
Thread motorControlTask(motor_control_task, NULL, osPriorityNormal, 1024);
DEBUG_PRINT_L0("Bd1> Initializing completed\r\n");
// Reset the motor controller;
/*
sdc2130.printf( "%RESET 32164987\r" );
sdc2130.printf( "%RESET 32164987\r" );
sdc2130.printf( "%RESET 32164987\r" );
sdc2130.printf( "%RESET 32164987\r" );
sdc2130.printf( "%RESET 32164987\r" );
*/
sdc2130.printf( "^ECHOF 1\r" );
sdc2130.printf( "^ECHOF 2\r" );
while(1) {
Thread::wait(20);
// sdc2130.printf( "?V\r" );
// sdc2130.printf( "^ECHOF 1\r" );
// sdc2130.printf( "^ECHOF 2\r" );
counter++;
if( counter >= 25 ){
led2 = !led2;
counter = 0;
if( limit_sw_rf == 0 ){
limitSw_Sts |= 0x01;
}
else{
limitSw_Sts &= 0xFE;
}
if( limit_sw_lb == 0 ){
limitSw_Sts |= 0x02;
}
else{
limitSw_Sts &= 0xFD;
}
}
Thread::wait(5);
}
}