---
# System prepended metadata

title: Motion Card
tags: [Robot id, ' software', ' Motion Card']

---

---
tags: Robot id, software, Motion Card
---
Motion Card
===

## MotionCard.h
```C++=
#ifndef MOTIONCARD
#define MOTIONCARD

#include "C:\\IMP3\\IMCDriver.h"  \\ 修改Path
#include "C:\\IMP3\\IMCDefine.h"  \\ 修改Path
#include <stdio.h>

#define AXIS 6
#define PI 3.1415926

void MotionCard_OpenCard();
void MotionCard_CloseCard();
void MotionCard_DAC(int Axis, double Voltage);
void MotionCard_ChangeTimer(TMRISR Timer);

#endif
```
## MotionCard.cpp
### Opencard
```C++=
void MotionCard_OpenCard()
{
    //  --- 軸卡初始化 ---
    /*  Bool IMC_OpenDevice(		// true：Initial IMP 模組成功 false：Initial IMP 模組失敗
                int nMode,			// 0：初始化 IMP 的 PCI 模式  1：初始化 IMP 的 Standalone 模式
                WORD wCardIndex)		*/
    int nRet = IMC_OpenDevice(0, 0);

    if (nRet == 0)
    {

        printf("Initialization Fails !");

    }
    else
    {
        //  --- 重置 IMP 模組 ---
        /*  IMC_GLB_ResetModule(
                    WORD ModuleID,		// RESET_ALL: All Modules 
                    WORD wCardIndex)	        // 欲控制的運動控制卡之編號，編號範圍 0~5 */
        IMC_GLB_ResetModule(RESET_ALL, 0); 

        // --- 遮閉 IMP 模組中斷功能 ---
        /*  IMC_GLB_SetInterruptMode(
                    int mode,			// IMC_ALL_INT_UNMASK: All Modules 
                    WORD wCardIndex) */
        IMC_GLB_SetInterruptMask(IMC_ALL_INT_UNMASK, 0); 


        //---------------- DAC & ADC ----------------

        for (int i = 0; i < AXIS; i++)
        {

            // --- 設定 DAC 命令源為軟體規劃 ---
            /* IMC_DAC_SelectSource( 
                    WORD channel,		// DAC channel number 0 ~ 7 
                    WORD source,		// DAC_CMD_SOFT：Source from DAC output buffer 
                    WORD wCardIndex)*/
            IMC_DAC_SelectSource(i, DAC_SOURCE_SOFT, 0);

            // --- 開啟 DAC 功能 ---
            /* IMC_DAC_EnableChannel( 
                    WORD channel ,		// DAC channel number 0 ~ 7 
                    WORD wEnable,		        // 1 開啟或 0 關閉指定 DA Channel 轉換功能 
                    WORD wCardIndex)*/
            IMC_DAC_EnableChannel(i, 1, 0);

        }

        // --- 開啟 DAC 功能 ---
        /* IMC_DAC_StartConverter( 
                WORD wStart,			// 1 開啟或 0 關閉 DAC 轉換功能 
                WORD wCardIndex)*/
        IMC_DAC_StartConverter(1, 0);

        for (int i = 0; i < AXIS; i++)
        {

            // --- DAC 電壓清空 ---
            /* IMC_DAC_SetOutputVoltage( 
                    WORD channel,		        // DAC channel number 0 ~ 7 
                    float fVoltage,		// 類比輸出電壓 (-10V ~ 10 V) 
                    WORD wCardIndex) */
            IMC_DAC_SetOutputVoltage(i, 0.0, 0);

        }

        //---------------- 中斷功能 ----------------

        // --- 設定計時器計時時間 1000 us (1豪秒) ---
        /* IMC_TMR_SetTimer( 
                float dfPeriod,			// 計時器時間(µs)，可設定範圍 (0 ~ 2^32 毫秒) 
                WORD wCardIndex) */
        IMC_TMR_SetTimer(1000, 0); 

        // --- 開啟計時器計時功能 ---
        /* IMC_TMR_SetTimerEnable( 
                WORD wEnable,			// 1 開啟或 0 關閉計時器功能 
                WORD wCardIndex) */
        IMC_TMR_SetTimerEnable(1, 0);

        // --- 開啟計時器中斷功能 ---
        /* IMC_TMR_SetTimerIntEnable(
                WORD wEnable,			// 1 開啟或 0 關閉計時器中斷功能 
                WORD wCardIndex) */
        IMC_TMR_SetTimerIntEnable(1, 0);

    }

}
```
### Closecard
```C++=
//==================== 關閉軸卡 ===================
void MotionCard_CloseCard()
{

    IMC_TMR_SetTimerIntEnable(0, 0); // 關閉計時器中斷功能
    IMC_TMR_SetTimerEnable(0, 0); // 關閉計時器計時功能

    for (int i = 0; i < AXIS; i++)
    {

        IMC_DAC_SetOutputVoltage(i, 0.0, 0); // DAC 電壓清空

    }

    IMC_DAC_StartConverter(0, 0); // 停止 DAC 轉換

    for (int i = 0; i < AXIS; i++)
    {

        IMC_DAC_EnableChannel(i, 0, 0); // 關閉DAC功能

    }
    // --- 關閉 IMP 模組 ---
    /* IMC_CloseIfOpen(
            WORD wCardIndex) */
    IMC_CloseIfOpen(0);
}
```
### DAC
```C++=
//====================== DAC ======================
void MotionCard_DAC(int Axis, double Voltage)
{

    IMC_DAC_SetOutputVoltage(Axis, Voltage, 0); // 設定輸出電壓

}
```
### Switch Timer
```C++=
//=================== 切換中斷 =====================
void MotionCard_ChangeTimer(TMRISR Timer)
{

    // --- 串接中斷服務函式 ---
    /*  IMC_TMR_SetISRFunction( 
            TMRISR   myTMR_ISR,			// User 自己撰寫的 Timer 中斷副程式之 Function Pointer
            WORD wCardIndex)*/
    IMC_TMR_SetISRFunction(Timer, 0);

}
```
### Servo On
```C++=
//================== Servo On ======================
void MotionCard_ServoOn()
{

    for (int i = 0; i < AXIS; i++)
    {

        // --- Servo On ---
        /* IMC_LIO_SetServoOn( 
                WORD wChannel,  
                WORD wCardIndex) */
        IMC_LIO_SetServoOn(i, 0); // ServoOn

    }
}
```
### Servo Off
```C++=
//================== Servo Off =====================
void MotionCard_Serco_Off()
{

    for (int i = 0; i < AXIS; i++)
    {

        // --- Servo Off ---
        /* IMC_LIO_SetServoOff( 
                WORD wChannel,  
                WORD wCardIndex) */
        IMC_LIO_SetServoOff(i, 0); // ServoOff

    }
}
```

### Read Encoder
```C++=
// ================ 編碼器設定 ===================
void MotionCard_Encoder(double(&JointEncRad)[AXIS])
{
    long MotorINCRPulse[AXIS] = { 0 };
    double MotorINCRRad[AXIS] = { 0.0 };

    for (int i = 0; i < AXIS; i++)
    {
        // --- "馬達端"增量型編碼器數值[Pulse] ---
        /* IMC_ENC_ReadCounter( 
                WORD enc_ch_no,			// encoder counter channel number (0~7)
                long *lCounter,			// 讀取Encoder counter 數值
                WORD wCardIndex) */
        IMC_ENC_ReadCounter(i, &MotorINCRPulse[i], 0);
        MotorINCRRad[i] = ((double)MotorINCRPulse[i] / 260000.0) * CircleRad; // "馬達端"增量型編碼器數值[Rad] , 增量型編碼器設定一圈65000*4個Pulse , 驅動器參數P1-46*軸卡4倍頻

        JointEncRad[i] = MotorINCRRad[i];
    }

}
```