shonen.hateblo.jp

やったこと,しらべたことを書く.

3軸加速度センサーを手に入れたので軽く触る(arduino)

加速度センサーとは

  • 加速度を検知するセンサー.
  • 加速度とは,速度の微分(変化量).
  • 高校物理で習う方程式F=maを思い出せば,物体に掛かっている力を検知するとも言えそう.
  • 一番検知しやすいのは重力.センサーが重力の方向に対してどの程度傾いているのか検知する.

使うもの

f:id:m_buyoh:20180320124117j:plain:w400

※画像の配線は本記事とは殆ど関係ないです

せっかくなので,以前使った128x64のOLEDを使用.

shonen.hateblo.jp

配線

非常に丁寧な取扱説明書が有ったので全く困りませんでした.

Vddは5V,設定は通常動作,outXをA0,outYをA1に接続.Z軸は興味ありません.

Vddを3.3Vではなく5Vにするのは,アナログ入出力のレンジを[0,5]Vにするため.

OLEDをi2c接続する.

プログラミング

display

まず,アナログ入力の値を表示.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif


void setup() {
  
  pinMode(A0, INPUT); // 加速度センサー outX
  pinMode(A1, INPUT); // 加速度センサー outY
  
  Serial.begin(9600);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3D (for the 128x64)
  
  display.display();
  delay(2000);

  display.setTextSize(1);
  display.setTextColor(WHITE);
}

void loop() {

  int acc_x = analogRead(A0);
  int acc_y = analogRead(A1);

  display.clearDisplay();
  display.setCursor(0,0);
  display.println(acc_x);
  display.println(acc_y);
  display.display();
}

理論上,水平に置くとx,yとも512になるはず.実際に計測してみたところ,x軸で512より若干小さい値が出た.

机が傾いているかも…?

センサーを垂直に傾けて数値を見てみると,x軸方向では255・725ぐらい.y軸は270・745くらい.xとyで20くらい差がある…

visualize

文字を表示していても面白くないので,センサーの値を二次元平面上の点に対応させて描画してみた.

void loop() {

  int acc_x = analogRead(A0);
  int acc_y = analogRead(A1);

  display.clearDisplay();

  int x = max(0, min(128, 64+(acc_x-512)/4));
  int y = max(0, min( 64, 32-(acc_y-512)/4));
  display.drawLine(64, 32, x, y, WHITE);
  
  display.display();
}

センサーの傾きが読み取れているのが分かる.

maiさん(@m_buyoh)がシェアした投稿 -

おまけ

帯を引くような感じの表示

const int delay_length = 20;
int delay_point[delay_length][2];
int delay_head_ptr = delay_length-1;

void loop() {

  int acc_x = analogRead(A0);
  int acc_y = analogRead(A1);

  int new_x = max(0, min(128, 64+(acc_x-512)/4));
  int new_y = max(0, min( 64, 32-(acc_y-512)/4));

  delay_point[delay_head_ptr][0] = new_x;
  delay_point[delay_head_ptr][1] = new_y;


  display.clearDisplay();
  
  for (int p = (delay_head_ptr + 1) % delay_length, q = delay_head_ptr;
       p != delay_head_ptr;
       q = p, p = (p + 1) % delay_length){
        
    display.drawLine(delay_point[p][0], delay_point[p][1], delay_point[q][0], delay_point[q][1], WHITE);
    
  }

  display.display();

  delay_head_ptr = (delay_head_ptr - 1 + delay_length) % delay_length;
}