F1風G Force Meterのプログラムコードなり
CPUボードはarduino UNO
3軸加速度センサーは秋月製MMA8452Qモジュール
ディスプレモニターはI2C通信のOLED 128×64(SSD1306)
VCCとGNDが逆なものがあるので接続に注意が必要
arduino IDEにてCプログラムコード作成
ブレッドボードでの配線接続方法は以下にゃり?
Cプログラムコードは以下にゃり?
/* -------------------------------------------------- *
* G Force Meter Program *
* -------------------------------------------------- *
* CPU: Arduino UNO CPU Board *
* C Compiler: *
* File Name: G_Force_Meter *
* Author: March *
* Created: 2018/07/03 *
* URL: http://ak12-march.is-best.net/ *
* -------------------------------------------------- */
#include <Wire.h>
#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g( U8G_I2C_OPT_DEV_0 | U8G_I2C_OPT_NO_ACK | U8G_I2C_OPT_FAST );
/* ----------------------------------------- *
* Define *
* ----------------------------------------- */
#define MMA8452_ADRS 0x1D
#define MMA8452_OUT_X_MSB 0x01
#define MMA8452_XYZ_DATA_CFG 0x0E
#define MMA8452_CTRL_REG1 0x2A
#define MMA8452_CTRL_REG1_ACTV_BIT 0x01
#define MMA8452_G_SCALE 2
/* ----------------------------------------- *
* Variabal *
* ----------------------------------------- */
volatile char g_buffer1[ 4 ];
char *charbuf1 = (char *)&g_buffer1;
volatile char g_buffer2[ 4 ];
char *charbuf2 = (char *)&g_buffer2;
volatile char g_buffer3[ 4 ];
char *charbuf3 = (char *)&g_buffer3;
/* ------------------------------------------------------ *
* Program Codes *
* ------------------------------------------------------ */
/* ----------------------------------------- *
* MMA8452 Data Read Byte Program *
* ----------------------------------------- */
byte MMA8452_ReadByte( byte adrs )
{
Wire.beginTransmission( MMA8452_ADRS );
Wire.write( adrs );
Wire.endTransmission( false );
Wire.requestFrom( MMA8452_ADRS, 1 );
while( !Wire.available( ) );
return ( Wire.read( ) );
}
/* ----------------------------------------- *
* MMA8452 Data Read Byte Array Program *
* ----------------------------------------- */
void MMA8452_ReadByteArray( byte adrs, int datlen, byte *dest )
{
Wire.beginTransmission( MMA8452_ADRS );
Wire.write( adrs );
Wire.endTransmission( false );
Wire.requestFrom( MMA8452_ADRS, datlen );
while( Wire.available( ) < datlen );
for( int x = 0; x < datlen; x++ ){
dest[ x ] = Wire.read( );
}
}
/* ----------------------------------------- *
* MMA8452 Data Read Write Program *
* ----------------------------------------- */
void MMA8452_WriteByte( byte adrs, byte dat )
{
Wire.beginTransmission( MMA8452_ADRS );
Wire.write( adrs );
Wire.write( dat );
Wire.endTransmission( false );
}
/* ----------------------------------------- *
* Cpu Init Program *
* ----------------------------------------- */
void setup( )
{
byte tmp;
// OLED画面の出力色設定
u8g.setColorIndex( 1 );
// 3軸加速度センサー初期化
tmp = MMA8452_ReadByte( MMA8452_CTRL_REG1 );
MMA8452_WriteByte( MMA8452_CTRL_REG1, tmp & ~(MMA8452_CTRL_REG1_ACTV_BIT) );
MMA8452_WriteByte( MMA8452_XYZ_DATA_CFG, (MMA8452_G_SCALE >> 2) );
tmp = MMA8452_ReadByte( MMA8452_CTRL_REG1 );
MMA8452_WriteByte( MMA8452_CTRL_REG1, tmp | MMA8452_CTRL_REG1_ACTV_BIT );
}
/* ----------------------------------------- *
* Main Loop Program *
* ----------------------------------------- */
void loop( )
{
byte buf[ 6 ];
float g_Force[ 3 ];
float g_Force_AngleXY;
float g_ForceNonMarkX, g_ForceNonMarkY, g_ForceMax, g_ForceCuff;
// G Force Data Read
MMA8452_ReadByteArray( MMA8452_OUT_X_MSB, 6, buf );
// floatとして変数格納
// G Force X:g_Force[0] | Y:g_Force[1] | Z:g_Force[3]
g_Force[ 0 ] = ( float( ( int( buf[ 0 ] << 8) | buf[ 1 ] ) >> 4 ) / ( ( 1 << 11 ) / MMA8452_G_SCALE ) );
g_Force[ 1 ] = ( float( ( int( buf[ 2 ] << 8) | buf[ 3 ] ) >> 4 ) / ( ( 1 << 11 ) / MMA8452_G_SCALE ) );
// 小数点2桁以下切捨て
g_Force[ 0 ] = (float)((int)(g_Force[ 0 ] * 100)) / 100;
g_Force[ 1 ] = (float)((int)(g_Force[ 1 ] * 100)) / 100;
// tan θ > ラジアン値変換
g_Force_AngleXY = atan( g_Force[ 0 ] / g_Force[ 1 ] );
// -符号をなくす
if( g_Force[ 0 ] < 0 ){ g_ForceNonMarkX = (-g_Force[ 0 ]); }
else{ g_ForceNonMarkX = g_Force[ 0 ]; }
if( g_Force[ 1 ] < 0 ){ g_ForceNonMarkY = (-g_Force[ 1 ]); }
else{ g_ForceNonMarkY = g_Force[ 1 ]; }
// 最大重力値
g_ForceMax = sqrt( (g_ForceNonMarkX*g_ForceNonMarkX) + (g_ForceNonMarkY*g_ForceNonMarkY));
// G Forceグラフ 最大スケール値
#define g_Force_guage_scale 1.0f
if( g_ForceMax > g_Force_guage_scale ){ g_ForceCuff = g_Force_guage_scale; }
else{ g_ForceCuff = g_ForceMax; }
// float > ASCII文字に変換
dtostrf( g_ForceMax, 3, 1, charbuf1 );
dtostrf( g_ForceNonMarkX, 3, 1, charbuf2 );
dtostrf( g_ForceNonMarkY, 3, 1, charbuf3 );
// OLED Display 出力
u8g.firstPage( );
do {
// G Force graph 枠Lineを描く
u8g.drawCircle( 96, 32, 30, U8G_DRAW_ALL );
u8g.drawCircle( 96, 32, 15, U8G_DRAW_ALL );
u8g.drawLine( 96, 2, 96.0f, 63.0f );
u8g.drawLine( 66, 32,126.0f, 32.0f );
u8g.drawFilledEllipse( 96, 32, 1, 1, U8G_DRAW_ALL );
u8g.drawRFrame( 0, 1, 61, 37, 3);
// 斜辺c 高さbを求める
float cosbuff = cos(g_Force_AngleXY);
float sinbuff = sin(g_Force_AngleXY);
// G Force Line Pointを描く
#define GFORCE_BALL_SIZE 3
if( g_Force[ 0 ] == 0.0 && g_Force[ 1 ] == 0.0f ){
u8g.drawFilledEllipse( 96.0f, 32.0f, GFORCE_BALL_SIZE, GFORCE_BALL_SIZE, U8G_DRAW_ALL );
} else if( g_Force[ 1 ] < 0.0f ){
u8g.drawLine( 96, 32, 96.0f-(((-30.0f) * g_ForceCuff) * cosbuff), 32.0f-(((-30.0f) * g_ForceCuff) * sinbuff) );
u8g.drawFilledEllipse( 96.0f-(((-30.0f) * g_ForceCuff) * cosbuff), 32.0f-(((-30.0f) * g_ForceCuff) * sinbuff), GFORCE_BALL_SIZE, GFORCE_BALL_SIZE, U8G_DRAW_ALL );
} else{
u8g.drawLine( 96, 32, 96.0f-((30.0f * g_ForceCuff) * cosbuff), 32.0f-((30.0f * g_ForceCuff) * sinbuff) );
u8g.drawFilledEllipse( 96.0f-((30.0f * g_ForceCuff) * cosbuff), 32.0f-((30.0f * g_ForceCuff) * sinbuff), GFORCE_BALL_SIZE, GFORCE_BALL_SIZE, U8G_DRAW_ALL );
}
// フォント設定
u8g.setFont( u8g_font_9x15B );
u8g.drawStrP( 8, 16, PSTR("Max G") );
u8g.drawStrP( 42, 34, PSTR("G") );
u8g.drawStrP( 2, 51, PSTR("G Force") );
// フォント設定
u8g.setFont( u8g_font_10x20r );
u8g.drawStr( 10, 34, charbuf1 );
// フォント設定
u8g.setFont( u8g_font_7x13r );
u8g.drawStrP( 0, 64, PSTR("X:") ); u8g.drawStrP( 42, 64, PSTR("Y:") );
u8g.drawStr( 14, 64, charbuf2 );
u8g.drawStr( 56, 64, charbuf3 );
} while( u8g.nextPage( ) );
delay( 50 );
}
u8glibのライブラリーをarduinoにインストールしてからビルドしてなり。
中華製arduino UNOは大体LMS1117の3端子レギュレターが使われています。
LMS1117の絶対定格電圧は15Vと低いので、エンジン始動後14V前後の電圧まであがる自動車などに使うのは危ないです。
そのためおいらは、LMS1117が使われていない絶対低格電圧が20V以上あるarduino UNOを使うようにしてるにゃん。
ディスカッション
コメント一覧
まだ、コメントがありません