LV8548 Motor Driver Stepper Motor Dc MOtor

Dependencies:   LV8548 mbed

Main.cpp

Committer:
yamasho
Date:
2018-11-19
Revision:
3:de46cb8b50cb
Parent:
2:77d8b59fa58c

File content as of revision 3:de46cb8b50cb:

#include "mbed.h"
#include "LV8548.h"

#define DC_ID "LV8548DC_Ver.2.0.0\n"
#define STEP_ID "LV8548Step_Ver.2.0.0\n"

//#define DEFAULT_BAUDRATE  (9600) 
#define DEFAULT_BAUDRATE  (19200) 
//#define DEFAULT_BAUDRATE  (115200) 

#define USE_DC_MOTOR      (false)            // true : dc motor  false: Stepper


#define _USE_DEBUG_     (1)
enum DCSerialCommandType {
    SRMES_GET_ID      = 0x03,        //  3
    SRMES_POLLING_ID  = 0x04,        //  4
//// For Dc Motor Control ////////
    SRMES_CTL_VOLTAGE = 'A',        // 'A'
    SRMES_ROTATION    = 'D',        // 'D'
    SRMES_PWM_FREQSET = 'g',        // 'g'
    SRMES_START_FLAG  = 'h',        // 'h'
//// For Stepper Motor Control ////////
    SRMES_STEP_ANGLE      = 'i',    // 'i'
    SRMES_ROTATION_ANGLE  = 'j',    // 'j'
    SRMES_ROTATION_TIME   = 'k',    // 'k'
    SRMES_ROTATION_STEP   = 'l',    // 'l'
    SRMES_ROTATION_STOP   = 'n',    // 'n'
    SRMES_ROTATION_FREE   = 'o',    // 'o'
};
//// For Dc Motor

    // Segment definition of serial message
    typedef struct
    {
      uint8_t motorNo;
      uint8_t duty;
    } __attribute__ ((packed)) SrMesDivCtlVoltage;

    typedef struct
    {
      uint8_t motorNo;
      DriverPwmOut select;
    } __attribute__ ((packed)) SrMesDivStartFlag;

    typedef struct
    {
      uint8_t motorNo;
      DriverPwmMode select;
    } __attribute__ ((packed)) SrMesDivRotation;
    
    typedef struct
    {
      uint8_t hz;
    } __attribute__ ((packed)) SrMesDivPwmFreqset;
    
  

SrMesDivCtlVoltage DcMtrvoltValue ;
SrMesDivRotation   DcMtrrotationValue;
SrMesDivStartFlag  DcMtrstartFlag;
SrMesDivPwmFreqset DcMtrfreqValue;

/// For Stepper Motor
    typedef struct
    {
        uint16_t angle;
    } __attribute__ ((packed)) SrMesDivSetStepAngle;

    typedef struct
    {
        uint16_t frequency;
        uint16_t deg;
        uint8_t rotation;
        uint8_t exp;
    } __attribute__ ((packed)) SrMesDivRotationDeg;

    typedef struct
    {
        uint16_t frequency;
        uint16_t time;
        uint8_t rotation;
        uint8_t exp;
    } __attribute__ ((packed)) SrMesDivRotationTime;

    typedef struct
    {
        uint16_t frequency;
        uint16_t step;
        uint8_t rotation;
        uint8_t exp;
    } __attribute__ ((packed)) SrMesDivRotationStep;



SrMesDivSetStepAngle   StepMtrAngleValue;
SrMesDivRotationDeg    StepMtrDegValue;
SrMesDivRotationTime   StepMtrTimeValue;
SrMesDivRotationStep   StepMtrStepValue;



//////// USB CDC SIDE DEBUG UART /////////////
/* pc の仮想ポートをwindows softで開ける */
//Serial pc(USBTX, USBRX); // tx, rx
//#if _USE_DEBUG_
//Serial uart(D1, D0); // tx, rx
//#endif
//////// OUT SIDE UART INPUT /////////////
#if _USE_DEBUG_
Serial uart(USBTX, USBRX); // tx, rx
#endif
Serial pc(D1, D0); // tx, rx

DigitalOut myled(LED1);
#if USE_DC_MOTOR
LV8548 MOTORDriver( D3,D5,D10,D11,DCMOTOR);     // SELECT DCMOTOR
#else
LV8548 MOTORDriver( D3,D5,D10,D11,STEPERMOTOR);     // STEP MOTOR
#endif

DigitalOut TEST(D12);
Ticker  Timer500;
Ticker  Timer1ms;
uint8_t LedImage;
uint8_t CommandTimer;

#define SBUFMAX     64
volatile uint8_t SerialBuffer[SBUFMAX];
volatile uint8_t RingBuffer[256];
volatile uint8_t RingReadpoint;
volatile uint8_t RingWritepoint;

/*******************************************/
/*    AA                                   */
/*   AAAA                     ii      ii   */
/*  AA  AA   sssss   cccc                  */
/*  AAAAAA  ss      cc       iii     iii   */
/*  AA  AA   ssss   cc        ii      ii   */
/*  AA  AA      ss  cc        ii      ii   */
/*  AA  AA  sssss    cccc    iiii    iiii  */
/*                                         */
/*******************************************/

uint8_t Ascii(uint8_t Data)
{
    switch(Data & 0xf)
    {
        case 0: return('0');
        case 1: return('1');
        case 2: return('2');
        case 3: return('3');
        case 4: return('4');
        case 5: return('5');
        case 6: return('6');
        case 7: return('7');
        case 8: return('8');
        case 9: return('9');
        case 0xA: return('A');
        case 0xB: return('B');
        case 0xC: return('C');
        case 0xD: return('D');
        case 0xE: return('E');
        case 0xF: return('F');
    }
    return (0);
}
/***************************************************************************************************************************/
/*  UU  UU                                  RRRRR                                                    IIII                  */
/*  UU  UU                    tt            RR  RR                    ii                              II                   */
/*  UU  UU   aaaa   rrrrr   tttttt          RR  RR   eeee    cccc           vv  vv   eeee             II    rrrrr    qqqqq */
/*  UU  UU      aa  rr  rr    tt            RRRRR   ee  ee  cc       iii    vv  vv  ee  ee            II    rr  rr  qq  qq */
/*  UU  UU   aaaaa  rr        tt            RRRR    eeeeee  cc        ii    vv  vv  eeeeee            II    rr      qq  qq */
/*  UU  UU  aa  aa  rr        tt            RR RR   ee      cc        ii     vvvv   ee                II    rr       qqqqq */
/*   UUUU    aaaaa  rr         ttt          RR  RR   eeee    cccc    iiii     vv     eeee            IIII   rr          qq */
/*                                                                                                                      qq */
/***************************************************************************************************************************/
void Read_Rx(void)
{
    RingWritepoint++;
    RingBuffer[RingWritepoint] = pc.getc();
    CommandTimer = 2;           // 2(最小1)ms後にコマンド処理
}
/***********************************************************************************************************/
/*   CCCC                                                           PPPPP                                  */
/*  CC  CC                                              dd          PP  PP                                 */
/*  CC       oooo   mm  mm  mm  mm  nnnnn    aaaa       dd          PP  PP   aaaa   rrrrr    sssss   eeee  */
/*  CC      oo  oo  mmmmmmm mmmmmmm nn  nn      aa   ddddd          PPPPP       aa  rr  rr  ss      ee  ee */
/*  CC      oo  oo  mmmmmmm mmmmmmm nn  nn   aaaaa  dd  dd          PP       aaaaa  rr       ssss   eeeeee */
/*  CC  CC  oo  oo  mm m mm mm m mm nn  nn  aa  aa  dd  dd          PP      aa  aa  rr          ss  ee     */
/*   CCCC    oooo   mm   mm mm   mm nn  nn   aaaaa   ddddd          PP       aaaaa  rr      sssss    eeee  */
/*                                                                                                         */
/***********************************************************************************************************/
void SerialRead(void)
{
 int i = 0;
    if(CommandTimer ) return;           /* 1ms 以上データ無しが安定してから読む */
 
 
    SerialBuffer[0] = '\0';
    while( RingWritepoint !=  RingReadpoint)
    {
        RingReadpoint++;
        SerialBuffer[i] = RingBuffer[RingReadpoint];
#if _USE_DEBUG_
        uart.putc(Ascii(SerialBuffer[i] >> 4)) ;
        uart.putc(Ascii(SerialBuffer[i] >> 0)) ;
        uart.putc(0x20);
#endif
        i++;
        if(i >= (SBUFMAX-1))
        {
#if _USE_DEBUG_
            uart.printf("Max over\n");
#endif
            SerialBuffer[i] = '\0';
            
        }
        continue;
    }
     
    switch( SerialBuffer[0] )
    {
            case SRMES_GET_ID:  // 3
            {
#if _USE_DEBUG_
                 uart.printf("Send Id\n");
#endif 
#if USE_DC_MOTOR
                 pc.printf(DC_ID);
#else
                 pc.printf(STEP_ID);
#endif
             }
             break;
 
             case SRMES_POLLING_ID:  // 4
             {
#if _USE_DEBUG_
                 uart.printf("Polling\n");
#endif
             }
             break;
/***************************************************************************************************/
/*  FFFFFF                          DDDD                    MM   MM                                */
/*  FF                              DD DD                   MMM MMM           tt                   */
/*  FF       oooo   rrrrr           DD  DD   cccc           MMMMMMM  oooo   tttttt   oooo   rrrrr  */
/*  FFFF    oo  oo  rr  rr          DD  DD  cc              MM M MM oo  oo    tt    oo  oo  rr  rr */
/*  FF      oo  oo  rr              DD  DD  cc              MM   MM oo  oo    tt    oo  oo  rr     */
/*  FF      oo  oo  rr              DD DD   cc              MM   MM oo  oo    tt    oo  oo  rr     */
/*  FF       oooo   rr              DDDD     cccc           MM   MM  oooo      ttt   oooo   rr     */
/*                                                                                                 */
/***************************************************************************************************/
            case SRMES_CTL_VOLTAGE: // 0x41
            {
                 DcMtrvoltValue = *(SrMesDivCtlVoltage *)&SerialBuffer[1];
#if _USE_DEBUG_
                 uart.printf("Voltage Commnad %2x %2x \n",DcMtrvoltValue.motorNo,DcMtrvoltValue.duty);
#endif
                 MOTORDriver.SetDcPwmDuty(DcMtrvoltValue.motorNo,(float)DcMtrvoltValue.duty/(float)100);
            }
            break;
        
            case SRMES_ROTATION:    // 0x44
            {
                 DcMtrrotationValue = *(SrMesDivRotation *)&SerialBuffer[1];
#if _USE_DEBUG_
                 uart.printf("Roteationcommand %2x %2x \n",DcMtrrotationValue.motorNo,DcMtrrotationValue.select);
#endif
                 MOTORDriver.SetDcPwmMode(DcMtrrotationValue.motorNo,DcMtrrotationValue.select);
            }
            break;
            
            case SRMES_PWM_FREQSET: // 0x67
            {
                 DcMtrfreqValue = *(SrMesDivPwmFreqset *)&SerialBuffer[1];
#if _USE_DEBUG_
                 uart.printf("Freq Hz  %2x \n",DcMtrfreqValue.hz);
#endif
                 switch(DcMtrfreqValue.hz)
                 {
                      case 0:   MOTORDriver.SetDcPwmFreqency( MOTOR_A, 7813 );
                                MOTORDriver.SetDcPwmFreqency( MOTOR_B, 7813 );
                                                           break;
                      case 1:   MOTORDriver.SetDcPwmFreqency( MOTOR_A,977 ); 
                                MOTORDriver.SetDcPwmFreqency( MOTOR_B,977 ); 
                                                           break;
                      case 2:   MOTORDriver.SetDcPwmFreqency( MOTOR_A,244 ); 
                                MOTORDriver.SetDcPwmFreqency( MOTOR_B,244 ); 
                                                           break;
                      case 3:   MOTORDriver.SetDcPwmFreqency( MOTOR_A,61 ); 
                                MOTORDriver.SetDcPwmFreqency( MOTOR_B,61 ); 
                                                           break;
                      default: break;
                 }
             }
             break;
 
            case SRMES_START_FLAG:  // 0x68
            {
                 DcMtrstartFlag = *(SrMesDivStartFlag *)&SerialBuffer[1];
#if _USE_DEBUG_
                 uart.printf("StartFlag command %2x %2x \n",DcMtrstartFlag.motorNo,DcMtrstartFlag.select);
#endif
                 MOTORDriver.SetDcOutPut(DcMtrstartFlag.motorNo,DcMtrstartFlag.select);
             }
             break;
/*******************************************************************************************************************/
/*  FFFFFF                           SSSS                                   MM   MM                                */
/*  FF                              SS  SS    tt                            MMM MMM           tt                   */
/*  FF       oooo   rrrrr           SS      tttttt   eeee   ppppp           MMMMMMM  oooo   tttttt   oooo   rrrrr  */
/*  FFFF    oo  oo  rr  rr           SSSS     tt    ee  ee  pp  pp          MM M MM oo  oo    tt    oo  oo  rr  rr */
/*  FF      oo  oo  rr                  SS    tt    eeeeee  pp  pp          MM   MM oo  oo    tt    oo  oo  rr     */
/*  FF      oo  oo  rr              SS  SS    tt    ee      ppppp           MM   MM oo  oo    tt    oo  oo  rr     */
/*  FF       oooo   rr               SSSS      ttt   eeee   pp              MM   MM  oooo      ttt   oooo   rr     */
/*                                                          pp                                                     */
/*******************************************************************************************************************/
            case SRMES_STEP_ANGLE:
            {
                StepMtrAngleValue = *(SrMesDivSetStepAngle *)&SerialBuffer[1];
#if _USE_DEBUG_
                 uart.printf("Step Angle command %4x Req:% \n",StepMtrAngleValue.angle);
#endif
                MOTORDriver.SetStepAngle(StepMtrAngleValue.angle/100);
            }
            break;

            case SRMES_ROTATION_ANGLE:
            {
                SrMesDivRotationDeg StepMtrDegValue = *(SrMesDivRotationDeg *)&SerialBuffer[1];
#if _USE_DEBUG_
                 uart.printf("Step Deg command  \n");
#endif
                 MOTORDriver.SetStepDeg(StepMtrDegValue.frequency/10, StepMtrDegValue.deg/100, StepMtrDegValue.rotation, StepMtrDegValue.exp);
             }
             break;
    
            case SRMES_ROTATION_TIME:
            {
                StepMtrTimeValue = *(SrMesDivRotationTime *)&SerialBuffer[1];
#if _USE_DEBUG_
                 uart.printf("Step Time command  \n");
#endif
                MOTORDriver.SetStepTime(StepMtrTimeValue.frequency/10, StepMtrTimeValue.time/10, StepMtrTimeValue.rotation, StepMtrTimeValue.exp);
             }
             break;
            
            case SRMES_ROTATION_STEP:
            {
#if _USE_DEBUG_
                 uart.printf("Step Step command  \n");
#endif
                StepMtrStepValue = *(SrMesDivRotationStep *)&SerialBuffer[1];
                MOTORDriver.SetStepStep(StepMtrStepValue.frequency/10, StepMtrStepValue.step/10, StepMtrStepValue.rotation,StepMtrStepValue.exp);
             }
             break;
  
           case SRMES_ROTATION_STOP:
           {
#if _USE_DEBUG_
                 uart.printf("Step Stop command  \n");
#endif
                MOTORDriver.SetStepStop();
            }
            break;

           case SRMES_ROTATION_FREE:
           {
#if _USE_DEBUG_
                 uart.printf("Step Free command  \n");
#endif
            
                 MOTORDriver.SetStepFree();
            }
            break;

            default:
            {
#if _USE_DEBUG_
         //        uart.printf("unknown command\n");
#endif
            }
            break;
     }
}
/***************************************************************************/
/*  TTTTTT                                  PPPPP                          */
/*    TT      ii                            PP  PP                         */
/*    TT            mm  mm   eeee   rrrrr   PP  PP  rrrrr    oooo    cccc  */
/*    TT     iii    mmmmmmm ee  ee  rr  rr  PPPPP   rr  rr  oo  oo  cc     */
/*    TT      ii    mmmmmmm eeeeee  rr      PP      rr      oo  oo  cc     */
/*    TT      ii    mm m mm ee      rr      PP      rr      oo  oo  cc     */
/*    TT     iiii   mm   mm  eeee   rr      PP      rr       oooo    cccc  */
/*                                                                         */
/***************************************************************************/
void Eventtimer500(void)
{
    LedImage = !LedImage;
}

void Eventtimer1ms(void)
{
   if(CommandTimer)  CommandTimer --;
}

/***********************************/
/*  MM   MM                        */
/*  MMM MMM           ii           */
/*  MMMMMMM  aaaa           nnnnn  */
/*  MM M MM     aa   iii    nn  nn */
/*  MM   MM  aaaaa    ii    nn  nn */
/*  MM   MM aa  aa    ii    nn  nn */
/*  MM   MM  aaaaa   iiii   nn  nn */
/*                                 */
/***********************************/
int main() 
{
    RingReadpoint = 0;
    RingWritepoint = 0;
    CommandTimer = 0;
    pc  .baud(DEFAULT_BAUDRATE);
#if _USE_DEBUG_
    uart.baud(115200);//DEFAULT_BAUDRATE);
    pc.printf("Program Start!\n");
    uart.printf("Program deb Start!\n");
#endif
    Timer500.attach(&Eventtimer500, 0.5);
    Timer1ms.attach(&Eventtimer1ms, 0.001);
    pc.attach(Read_Rx, Serial::RxIrq);
    while(1) {
        SerialRead();
        myled = LedImage; // LED is ON
    }

}