新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 無刷云臺代碼分析

        無刷云臺代碼分析

        作者: 時間:2016-11-30 來源:網絡 收藏
        1、_044.ino為主程序

        void loop() 為主程序大循環
        主要功能讀取MPU6050平計算出相應數據
        2、定時中斷驅動電機轉動

        本文引用地址:http://www.104case.com/article/201611/323783.htm

        //用這個程序改多軸飛控一定很穩定。可以用它作為一個模塊把算出的數據發給KK_C再進行控制。
        /********************************/
        /* Motor Control Routines */
        /********************************/
        ISR( TIMER1_OVF_vect )
        {//定時中斷嗎?在這里輸出電機控制信號嗎?
        freqCounter++;
        if(freqCounter==(CC_FACTOR/MOTORUPDATE_FREQ))
        {//中斷CC_FACTOR/MOTORUPDATE_FREQ次執行以下程序 即輸出頻率

        // Move pitch and roll Motor
        deviderCountPitch++;//這里用計數的方式有什么作用喃?pitchDevider越大時延時會越長,好像不太好。直接執行不好嗎?
        //if(abs(pitchDevider)>=1) //胥擬改進 大于或等于1說明有數據才進行調整,免得電機不斷輸出發熱和抖動
        if(deviderCountPitch >= abs(pitchDevider)) //abs(pitchDevider)=計算參數的絕對值,即不算符號,只管數值
        //分析如果pitchDevider=0時,每次都會執行它,用問題嗎?=0時會不斷輸出到電機,有點問題哦!
        {//Roll電機
        fastMoveMotor(config.motorNumberRoll, rollDirection,pwmSinMotorRoll);
        deviderCountRoll=0;
        }
        freqCounter=0;
        }
        }
        //=======================================
        fastMoveMotor電機驅動子程序

        // Hardware Abstraction for Motor connectors,
        // DO NOT CHANGE UNLES YOU KNOW WHAT YOU ARE DOING !!!
        #define PWM_A_MOTOR1 OCR2A
        #define PWM_B_MOTOR1 OCR1B
        #define PWM_C_MOTOR1 OCR1A

        #define PWM_A_MOTOR0 OCR0A
        #define PWM_B_MOTOR0 OCR0B
        #define PWM_C_MOTOR0 OCR2B
        //以上是引腳定義嗎?
        void fastMoveMotor(uint8_t motorNumber, int dirStep,uint8_t* pwmSin)
        {//fastMoveMotor(uint8_tmotorNumber(電機選擇?X軸/Y軸), int dirStep(正轉1、反轉-1或不轉0),uint8_t* pwmSin(數據表首地址256字節))
        if (motorNumber == 0)
        {//改這里就可以改成步進電機的了。:)
        //用單片機寫個步進電機驅動,再用兩個端口進行控制。一個端口控制方向,一個端口控制步數
        currentStepMotor0 += dirStep;//currentStepMotor0 為原來的位置 dirStep=(-1,0,1)
        PWM_A_MOTOR0 = pwmSin[currentStepMotor0];//查表輸出A
        PWM_B_MOTOR0 = pwmSin[(uint8_t)(currentStepMotor0 + 85)];//查表輸出B
        PWM_C_MOTOR0 = pwmSin[(uint8_t)(currentStepMotor0 + 170)];//查表輸出C 總步數85*3=255為一圈
        }

        if (motorNumber == 1)
        {
        currentStepMotor1 += dirStep;
        PWM_A_MOTOR1 = pwmSin[currentStepMotor1] ;
        PWM_B_MOTOR1 = pwmSin[(uint8_t)(currentStepMotor1 + 85)] ;
        PWM_C_MOTOR1 = pwmSin[(uint8_t)(currentStepMotor1 + 170)] ;
        }
        }

        //==================================================
        pitchDevider = constrain(maxDegPerSecondPitch / (pitchPID + 0.000001), -15000,15000)*2;
        pitchDirection = sgn(pitchDevider) * config.dirMotorPitch;//計算電機輸出數據-1,0,1 只轉一點點
        rollDevider = constrain(maxDegPerSecondRoll / (rollPID + 0.000001), -15000,15000)*2;
        rollDirection = sgn(rollDevider) * config.dirMotorRoll;//計算電機輸出數據-1,0,1


        int8_t sgn(int val) {
        if (val < 0) return -1;
        if (val==0) return 0;
        return 1;
        }
        //以下是主程序分析
        //功能分析:除了通過陀螺儀和加速度儀數據運算調整兩個電機移動以外還加入了外部控制的調整量
        //主程序內只算出移動數據,在中斷中才不斷的進行輸出動作
        /**********************************************/
        /* Main Loop */
        /**********************************************/
        int count=0;
        void loop()
        {

        sampleTimePID = (micros()-timer)/1000000.0/CC_FACTOR; // in Seconds! 檢測時間控制設置 通過CC_FACTOR調節因子調節大小?
        //得到上次運行到本次運行的時間長短,用于PID算法
        timer = micros();//存本次時間,用于和下次時間的比較。
        //定時器會溢出嗎?要進行相應處理嗎?大約50天溢出一次,要進行確認!

        // Update raw Gyro //更新陀螺儀數據
        updateRawGyroData(&gyroRoll,&gyroPitch);//讀取陀螺儀數據

        // Update DMP data approximately at 50Hz to save calculation time.


        if(config.useACC==1)//根據變量控制程序流程
        {//流程1 執行頻率不同
        //周期長
        count++;
        // Update ACCdataapproximately at 50Hz to save calculation time.
        if(count == 20)
        {
        sampleTimeACC = (micros()-timerACC)/1000.0/CC_FACTOR; // in Seconds * 1000.0 to account for factor 1000 in parameters
        timerACC=timer;//計算時間差值
        //{Serial.print(sampleTimeACC,5);Serial.print(" ");Serial.println(sampleTimePID,5);}
        mpu.getAcceleration(&x_val,&y_val,&z_val);//讀三軸加速度值中嗎?
        }
        if(count == 21)
        //roll角度控制計算
        rollAngleACC = 0.9 * rollAngleACC + 0.1 * ultraFastAtan2(-y_val,-z_val); //rollAngleACC = 0.8 * rollAngleACC + atan2(-y_val,-z_val)*57.2957795 * 0.2;
        if(count == 22)
        {//pitch角度控制計算
        pitchAngleACC = 0.9 * pitchAngleACC + 0.1 * -ultraFastAtan2(-x_val,-z_val);//角度計算嗎?
        count=0;
        if(config.accOutput==1){Serial.print(pitchAngleACC);Serial.print(" ACC ");Serial.println(rollAngleACC);}
        // {Serial.print(gyroPitch);Serial.print(" ACC G ");Serial.println(gyroRoll);}
        }
        }
        else // Use DMP
        {//流程2
        //周期短
        //不進行加速度計算嗎?
        if(count == 2)
        {//pitch角度控制計算
        pitchAngleACC = -asin(-2.0*(q.x * q.z - q.w * q.y)) * 180.0/M_PI;//角度計算嗎?
        count=0;
        if(config.dmpOutput==1){Serial.print(pitchAngleACC);Serial.print(" DMP ");Serial.println(rollAngleACC);}
        // {Serial.print(gyroPitch);Serial.print(" DMP G ");Serial.println(gyroRoll);}
        }
        if(count == 1)
        {//roll角度控制計算
        rollAngleACC = ultraFastAtan2(2.0*(q.y * q.z + q.w * q.x), q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z);
        rollAngleACC = -1*(sgn(rollAngleACC) * 180.0 - rollAngleACC);//角度計算嗎?
        count++;
        }
        if(mpuInterrupt) 判斷MPU 中斷標志嗎?
        { //兩個不同地方的sampleTimeACC有沖突嗎?
        sampleTimeACC = (micros()-timerACC)/1000.0/CC_FACTOR; // in Seconds * 1000.0 to account for factor 1000 in parameters
        timerACC=timer;//計算時間差值通過CC_FACTOR調節因子調節大小?
        //有中斷產生時讀取MPU6050的相應數據嗎?
        mpu.getFIFOBytes(fifoBuffer, 18); // I2C 800000L : 1300-1308 micros fo 42 bytes, ~540 micros for 16bytes
        mpu.dmpGetQuaternion(&q, fifoBuffer); // I2C 800000L : 64-68 micros
        mpuInterrupt = false;
        count++;
        }
        }


        上一頁 1 2 下一頁

        關鍵詞: 無刷云臺代碼分

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 和平区| 商都县| 苏尼特右旗| 洞口县| 怀化市| 四会市| 娱乐| 湖口县| 高州市| 土默特右旗| 紫云| 连城县| 英德市| 阿勒泰市| 大庆市| 普兰店市| 正阳县| 青川县| 邵阳县| 和政县| 观塘区| 元阳县| 马尔康县| 巴青县| 江津市| 贡觉县| 黎川县| 土默特右旗| 深泽县| 白河县| 武夷山市| 枞阳县| 邛崃市| 义乌市| 腾冲县| 鸡西市| 万州区| 汉源县| 高清| 霞浦县| 枝江市|