ご覧いただきありがとうございます。
子供のころからものづくりが好きな
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アダプタの通信速度がデフォルトのままで遅いことが影響していると思われるため、通信速度の設定変更を行い、改善するか確認してみようと思います。
ではまた。
人気記事