タイマーでループ間の所要時間を測る | おやじクリエイターがお小遣いで楽しむ工作室

おやじクリエイターがお小遣いで楽しむ工作室

趣味のことを中心に書きます。

 

 

 ご覧いただきありがとうございます。ニコニコ

 

 子供のころからものづくりレンチが好きな

 50代のおじさんです。

 

 「PICマイコン」を使った電子工作や、

 「Unity」というゲームエンジンを使った

遊びについて書いています。

 

ものづくりで悪戦苦闘している様子を

 キョロキョロ 見て行ってください。

 

 

 

 

 

 

 

前回 からPICマイコン側で回転数を算出する方法を検討していますが、

 

今回はタイマーを使ってwhile()ループ間の所要時間を出す方法を考えてみました。

 

 

  MCC設定

 

TMR0(タイマー0)を追加。

 

 

 

 

タイマー0の設定画面。割り込みを有効にし、タイマーの周期を1msにします。

 

 

 

  PICコード

 

タイマー0の割り込み処理で1msごとにカウントを1増やし、

Printfで出力したらカウントを0に戻します。

※赤字はタイマー割り込みに関する部分。

 


#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/examples/i2c_master_example.h"
#include <stdio.h>
#include <math.h>

uint8_t Buffer1[6];
int16_t cpx, cpy, cpz;
//double angle;
double vectorA[3] = {100.0, 100.0, 100.0};
double vectorB[3] = {100.0, 100.0, 100.0};
double counter = 0; // ???????????

double dotProduct(double A[], double B[]) {
    return A[0] * B[0] + A[1] * B[1] + A[2] * B[2];
}

double vectorMagnitude(double V[]) {
    return sqrt(V[0] * V[0] + V[1] * V[1] + V[2] * V[2]);
}

double angleBetweenVectors(double A[], double B[]) {
    double dot = dotProduct(A, B);
    double magnitudeA = vectorMagnitude(A);
    double magnitudeB = vectorMagnitude(B);

    double cosTheta = dot / (magnitudeA * magnitudeB);
    double thetaRad = acos(cosTheta);

    // Convert radians to degrees
    //double thetaDeg = thetaRad * (180.0 / M_PI);
    //return thetaRad;
    //return thetaDeg;
    return cosTheta;
}

void TMR0_Interrupt(){
    counter++;   
}

void main(void)
{
    // initialize the device
    SYSTEM_Initialize();
    // When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
    // Use the following macros to:
    TMR0_SetInterruptHandler(TMR0_Interrupt);
    // Enable the Global Interrupts
    INTERRUPT_GlobalInterruptEnable();

    // Enable the Peripheral Interrupts
    INTERRUPT_PeripheralInterruptEnable();

    // Disable the Global Interrupts
    //INTERRUPT_GlobalInterruptDisable();

    // Disable the Peripheral Interrupts
    //INTERRUPT_PeripheralInterruptDisable();
    
    I2C_Write1ByteRegister(0x68, 0x6B, 0x00); //Internal 8MHz oscillator
    I2C_Write1ByteRegister(0x68, 0x6A, 0x00); //I2C MasterMode OFF
    I2C_Write1ByteRegister(0x68, 0x37, 0x02); //I2C_BYPASS_EN
    I2C_Write1ByteRegister(0x68, 0x23, 0xFF); //FIFO Enable
    I2C_Write1ByteRegister(0x68, 0x1B, 0x18); //Full Scale Range ?2000?/s
    
    I2C_Write1ByteRegister(0x0D, 0x0B, 0x01); 
    I2C_Write1ByteRegister(0x0D, 0x09, 0x11);   

    while (1)
    {
        // Add your application code
        I2C_ReadDataBlock(0x68, 0x43, Buffer1, 6);
        cpx = Buffer1[0] << 8 | Buffer1[1];//????
        cpy = Buffer1[2] << 8 | Buffer1[3];
        cpz = Buffer1[4] << 8 | Buffer1[5];
        vectorB[0]=cpx;
        vectorB[1]=cpy;
        vectorB[2]=cpz;
        double angle = angleBetweenVectors(vectorA, vectorB);
        printf("count= %f, angle= %5.1f\r\n",counter, angle);
        counter=0;
       
        vectorA[0]=vectorB[0];
        vectorA[1]=vectorB[1];
        vectorA[2]=vectorB[2];     
    }
}
 

 

 

  結果

 

PCのTeraterm画面です。while()ループ間が120ms程度と、

実際に取得したい時間の10倍程度かかっており、これでは使えません。

※angle=の部分はcosθの値を表示。

 

 

 

 

  次回予告

 

Bluetoothアダプタの通信速度がデフォルトのままで遅いことが影響していると思われるため、通信速度の設定変更を行い、改善するか確認してみようと思います。

ではまた。

 

 

同じネタで投稿する

 

他の投稿ネタを確認する