Dependents:   YMotor

YMotorDriverBase.cpp

Committer:
inst
Date:
2015-08-23
Revision:
0:a2bbf76ca734
Child:
1:c8ed08beefb9

File content as of revision 0:a2bbf76ca734:

#include "mbed.h"
#include "PWMOut.h"
#include "YMotorDriverBase.h"

const PinName YMotorDriverBase::mMotorDriveDoutPinName[] = {
    dp6, dp9, dp13, dp14
};
const PinName YMotorDriverBase::mMotorDrivePwmPinName   = dp1;
const PinName YMotorDriverBase::mLEDPinName             = dp28;
const PinName YMotorDriverBase::mSerialPinName[]        = {
//  tx    rx
    dp16, dp15
};
const PinName YMotorDriverBase::mI2CPinName[] = {
//  sda  scl
    dp5, dp27
};
const int YMotorDriverBase::mPwmCycle_us  = 300;
const float YMotorDriverBase::mMaxDuty    = 0.90f;
const float YMotorDriverBase::mMinDuty    = 0.30f;

YMotorDriverBase::YMotorDriverBase( char address ) : mAddress( address ){
    mI2C = new I2CSlave( mI2CPinName[ 0 ], mI2CPinName[ 1 ] );
    mI2C->address( mAddress );
    
    for ( int i = 0; i < 4; ++i ){
        mMotorDriveDout[ i ] = new DigitalOut( mMotorDriveDoutPinName[ i ] );
    }
    
    mAction = RELEASE;
    
    mMotorDrivePwm = new PWMOut( mMotorDrivePwmPinName );
    mMotorDrivePwm->setPeriod_us( mPwmCycle_us );
    mMotorDrivePwm->setDuty( mMinDuty );
    
    mLED = new DigitalOut( mLEDPinName, 0 );
    
    write();
}

YMotorDriverBase::~YMotorDriverBase(){
    delete mI2C;
}

void YMotorDriverBase::update(){
     switch ( mI2C->receive() ){
        case I2CSlave::ReadAddressed:{
             char buf[] = { mMinDuty * 255.0f, mMaxDuty * 255.0f };
             mI2C->write( buf, 2 );
            break;
        }
        case I2CSlave::WriteGeneral:
            break;
             
        case I2CSlave::WriteAddressed:{
            char buf[ 2 ];
            mI2C->read( buf, 2 );
            // 初めの1Byteはモータの動作を指定する
            mAction = static_cast< MotorAction >( buf[ 0 ] );
            // 次の1Byteは0~255でDutyを指定する
            mDuty = static_cast< float >( buf[ 1 ] ) / 255.0f;
            break;
        }
            
        case I2CSlave::NoData:
            break;
     }
     
     write();
}
void YMotorDriverBase::write(){
    updatePwmDuty();
    
    switch ( mAction ){
        case FORWARD:
            mMotorDriveDout[ 0 ]->write( 0 );
            mMotorDriveDout[ 1 ]->write( 1 );
            mMotorDriveDout[ 2 ]->write( 1 );
            mMotorDriveDout[ 3 ]->write( 0 );
            break;
            
        case REVERSE:
            mMotorDriveDout[ 0 ]->write( 1 );
            mMotorDriveDout[ 1 ]->write( 0 );
            mMotorDriveDout[ 2 ]->write( 0 );
            mMotorDriveDout[ 3 ]->write( 1 );
            break;
            
        case BRAKE:
            mMotorDriveDout[ 0 ]->write( 0 );
            mMotorDriveDout[ 1 ]->write( 0 );
            mMotorDriveDout[ 2 ]->write( 0 );
            mMotorDriveDout[ 3 ]->write( 0 );
            break;
            
        case RELEASE:
            mMotorDriveDout[ 0 ]->write( 1 );
            mMotorDriveDout[ 1 ]->write( 1 );
            mMotorDriveDout[ 2 ]->write( 0 );
            mMotorDriveDout[ 3 ]->write( 0 );
            break;
            
        default:
            mAction = RELEASE;
            mMotorDriveDout[ 0 ]->write( 1 );
            mMotorDriveDout[ 1 ]->write( 1 );
            mMotorDriveDout[ 2 ]->write( 0 );
            mMotorDriveDout[ 3 ]->write( 0 );
            break;
    }
}

void YMotorDriverBase::updatePwmDuty(){
    static float prevDuty = mMinDuty;
    float d = middle( mMinDuty, mDuty, mMaxDuty );
    
    if ( d != prevDuty ){
        mMotorDrivePwm->setDuty( d );
    }
    prevDuty = d;
}

void YMotorDriverBase::setPercent( float p ){
    p = middle( 0.0f, p, 1.0f );
    mDuty = p * mMaxDuty + ( 1.0f - p ) * mMinDuty;
}