フリスクケースの中身はこんな感じ。
作り方を教えて欲しいという方がいらっしゃったのでスケッチを貼っておきます。いらないコードがいっぱいくっついていますが、将来性を考えて残してあります。
注:includeの<>は半角の<>に書き換える事。
// MPU-6050 Accelerometer + Gyro
#include <Wire.h>
#include "SparkFunBME280.h"
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SSD1306_I2C_ADDRESS 0x3C // 011110+SA0+RW - 0x3C or 0x3D
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
BME280 sensor;
unsigned long ttime;
unsigned long stime;
unsigned long old_stime;
int interval_time = 600; // second
#define MPU6050_ACCEL_XOUT_H 0x3B // R
#define MPU6050_WHO_AM_I 0x75 // R
#define MPU6050_PWR_MGMT_1 0x6B // R/W
#define MPU6050_I2C_ADDRESS 0x68
typedef union accel_t_gyro_union {
struct {
uint8_t x_accel_h;
uint8_t x_accel_l;
uint8_t y_accel_h;
uint8_t y_accel_l;
uint8_t z_accel_h;
uint8_t z_accel_l;
uint8_t t_h;
uint8_t t_l;
uint8_t x_gyro_h;
uint8_t x_gyro_l;
uint8_t y_gyro_h;
uint8_t y_gyro_l;
uint8_t z_gyro_h;
uint8_t z_gyro_l;
}
reg;
struct {
int16_t x_accel;
int16_t y_accel;
int16_t z_accel;
int16_t temperature;
int16_t x_gyro;
int16_t y_gyro;
int16_t z_gyro;
}
value;
};
int DL = 500; //待ち時間
int dt = 150; //周期
int unsigned long time; //現在時間
float angle_x;
float angle_y;
float angle_z;
float kx = 1.0; //補正係数x
float ky = 1.0; //補正係数y
float kz = 1.0; //補正係数z
float dx = 0.0; //オフセットx
float dy = 0.0; //オフセットy
float dz = 0.0; //オフセットz
float d_alt = 0.0; //オフセットalt
float ave_tmp ;
float ave_hum ;
float ave_prs ;
float ave_alt ;
float ave_dp ;
double ave_di ;
int ch;
int old_sw = 1;
int new_sw = 1;
void setup() {
pinMode( 8, INPUT_PULLUP);
pinMode( 7, INPUT_PULLUP);
pinMode( 6, INPUT_PULLUP);
Wire.begin();
//Serial.begin(9600);
int error;
uint8_t c;
error = MPU6050_read (MPU6050_WHO_AM_I, &c, 1);
error = MPU6050_read (MPU6050_PWR_MGMT_1, &c, 1);
MPU6050_write_reg (MPU6050_PWR_MGMT_1, 0);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
// Serial.println(F("SSD1306 allocation failed"));
for (;;); // Don't proceed, loop forever
}
sensor.setI2CAddress(0x76);
sensor.beginI2C(); // Wire を用いて I2C 接続開始
sensor.setFilter(1); // フィルタ係数: 2
sensor.setStandbyTime(0); // スタンバイ時間: 0.5 ms
sensor.setTempOverSample(1); // オーバーサンプリング x1
sensor.setPressureOverSample(1); // オーバーサンプリング x1
sensor.setHumidityOverSample(1); // オーバーサンプリング x1
}
void loop() {
ttime = millis();
stime = ttime / 1000;
int error;
float dT;
accel_t_gyro_union accel_t_gyro;
error = MPU6050_read (MPU6050_ACCEL_XOUT_H, (uint8_t *) &accel_t_gyro, sizeof(accel_t_gyro));
uint8_t swap;
#define SWAP(x,y) swap = x; x = y; y = swap
SWAP (accel_t_gyro.reg.x_accel_h, accel_t_gyro.reg.x_accel_l);
SWAP (accel_t_gyro.reg.y_accel_h, accel_t_gyro.reg.y_accel_l);
SWAP (accel_t_gyro.reg.z_accel_h, accel_t_gyro.reg.z_accel_l);
SWAP (accel_t_gyro.reg.t_h, accel_t_gyro.reg.t_l);
SWAP (accel_t_gyro.reg.x_gyro_h, accel_t_gyro.reg.x_gyro_l);
SWAP (accel_t_gyro.reg.y_gyro_h, accel_t_gyro.reg.y_gyro_l);
SWAP (accel_t_gyro.reg.z_gyro_h, accel_t_gyro.reg.z_gyro_l);
float acc_x = accel_t_gyro.value.x_accel / 16384.0; //FS_SEL_0 16,384 LSB / g
float acc_y = accel_t_gyro.value.y_accel / 16384.0;
float acc_z = accel_t_gyro.value.z_accel / 16384.0;
float acc_angle_x = atan2(acc_x, acc_z) * 360 * kx / 2.0 / PI;
float acc_angle_y = atan2(acc_y, acc_z) * 360 * ky / 2.0 / PI;
float acc_angle_z = atan2(acc_x, acc_y) * 360 * kz / 2.0 / PI;
float gyro_x = accel_t_gyro.value.x_gyro / 131.0; //FS_SEL_0 131 LSB / (°/s)
float gyro_y = accel_t_gyro.value.y_gyro / 131.0;
float gyro_z = accel_t_gyro.value.z_gyro / 131.0;
angle_x = (angle_x * 0.9) + (acc_angle_x * 0.1) ;
angle_y = (angle_y * 0.9) + (acc_angle_y * 0.1) ;
angle_z = (angle_z * 0.9) + (acc_angle_z * 0.1) ;
//BME280
float tmp = sensor.readTempC();
ave_tmp = (ave_tmp * 0.9) + (tmp * 0.1) ;
float hum = sensor.readFloatHumidity();
ave_hum = (ave_hum * 0.9) + (hum * 0.1) ;
float prs = sensor.readFloatPressure() / 100.0 ;
ave_prs = (ave_prs * 0.9) + (prs * 0.1) ;
float alt = sensor.readFloatAltitudeMeters();
ave_alt = (ave_alt * 0.9) + (alt * 0.1) ;
float dp = sensor.dewPointC();
ave_dp = (ave_dp * 0.9) + (dp * 0.1) ;
double di = 0.81 * tmp + 0.01 * hum * (0.99 * tmp - 14.3) + 46.3;
ave_di = (di * 0.9) + (di * 0.1) ;
//offset
if (digitalRead(6) == LOW ) {
dx = 0.0 ;
dy = 0.0 ;
dz = 0.0 ;
d_alt = 0.0 ;
}
if (digitalRead(7) == LOW ) {
dx = angle_x ;
dy = angle_y ;
dz = angle_z ;
d_alt = ave_alt ;
}
float a_x = angle_x - dx ;
float a_y = angle_y - dy ;
float a_z = angle_z - dz ;
float slope_x = tan(a_x * ( PI / 180) ) * 100.0 ;
float slope_y = tan(a_y * ( PI / 180) ) * 100.0 ;
float slope_z = tan(a_z * ( PI / 180) ) * 100.0 ;
float a_alt = ave_alt - d_alt ;
new_sw = digitalRead(8) ;
if (new_sw == 0 & old_sw == 1) {
ch = !ch;
}
old_sw = new_sw ;
if (ch == 1) {
display.clearDisplay();
display.setTextSize(3);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print(a_alt, 0);
display.println("m");
display.print(slope_y, 1);
//display.setTextSize(1);
display.print("%");
//display.setTextSize(3);
display.display(); // ディスプレイへの表示
} else {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print(ave_tmp, 1);
display.print("C ");
display.print(ave_hum, 0);
display.println("%");
display.print(ave_prs, 0);
display.println("hpa");
display.print(a_alt, 0);
display.print("m ");
display.print(a_y, 1);
display.println("");
display.print(ave_dp, 1);
display.print(" ");
display.print(ave_di, 1);
display.display(); // ディスプレイへの表示
}
}
// MPU6050_read
int MPU6050_read(int start, uint8_t *buffer, int size) {
int i, n, error;
Wire.beginTransmission(MPU6050_I2C_ADDRESS);
n = Wire.write(start);
if (n != 1)
return (-10);
n = Wire.endTransmission(false); // hold the I2C-bus
if (n != 0)
return (n);
// Third parameter is true: relase I2C-bus after data is read.
Wire.requestFrom(MPU6050_I2C_ADDRESS, size, true);
i = 0;
while (Wire.available() && i < size) {
buffer[i++] = Wire.read();
}
if ( i != size)
return (-11);
return (0); // return : no error
}
// MPU6050_write
int MPU6050_write(int start, const uint8_t *pData, int size) {
int n, error;
Wire.beginTransmission(MPU6050_I2C_ADDRESS);
n = Wire.write(start); // write the start address
if (n != 1)
return (-20);
n = Wire.write(pData, size); // write data bytes
if (n != size)
return (-21);
error = Wire.endTransmission(true); // release the I2C-bus
if (error != 0)
return (error);
return (0); // return : no error
}
// MPU6050_write_reg
int MPU6050_write_reg(int reg, uint8_t data) {
int error;
error = MPU6050_write(reg, &data, 1);
return (error);
}