ピエゾセンサの見える化

ピエゾニューマティックセンサはうまく使うとなかなか良いのですが、それなりに癖があって使い方に悩まれる方も多いようです。

波形を確認しながら試行錯誤できたらいいんじゃないかと思って作ってみました。

使うもの

seeeduino xiao
今回はAD変換に差動入力を使いたいので差動機能のあるSAM21の乗ったこいつを選択。差動入力できればなんでもよかったのですが、xiao使ってみたかったのとxiao用に差動入力も出来るlibraryをつくってくださっている方がいたので。
0.96インチ、i2c接続のoled
波形表示用。SPIの方が速いらしいのでSPIでもいいんですが。ラインの引き回しが面倒だったので。
1M~10Mオーム程度の抵抗
抵抗が大きくなるほど感度が高くなります。
その他
リード付きのピエゾ素子かピエゾニューマティックセンサのピエゾと2.5mmモノラルジャック。裸のリード線付きのピエゾ素子を使うのであれば、ビニールテープとかで金属部分に直接触れないようにした方が良いかもです。 あとブレッドボードとか
Arduinoとか
seeeduino xiaoとかoledとか使えるようにしとく

配線図

配線図 配線図

プログラム

Sasapea's Labに行って ADCライブラリと参照ライブラリ(ADCライブラリのページの下の方にリンクがあります)をもらってきます。 もらってきた.hファイルと.cppファイルをソースコードと同じフォルダに入れておきます。
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <Wire.h>
#include "adconverter.h"

// DISPLAY SETTINGS
#define OLED_ADDRESS 0x3C
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define DS 80

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1,1000000UL,400000UL);

int  dataBuff[DS];
int  bufMax,bufMin;

unsigned long times=0;
uint8_t SAMPLING_FREQUENCY =30;

void setup() {
  display.begin(SSD1306_SWITCHCAPVCC,OLED_ADDRESS);
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.clearDisplay();

  ADConverter::begin( ADCONVERTER_PRESCALER_DIV64 );
  ADConverter::input(ADCONVERTER_MUXPOS_PIN_A0,ADCONVERTER_MUXNEG_PIN_A1,ADCONVERTER_GAIN_DIV2);
  ADConverter::reference(ADCONVERTER_REFSEL_INTVCC0);
  ADConverter::start(true);
}

void loop() {
  while(1000/SAMPLING_FREQUENCY>((millis()-times))) ;
  times=millis();

  display.clearDisplay();
  waveRead();
  wavePlot();
  display.display();                        // バッファを転送して表示
}

void waveRead() {
  bufMax=0;
  bufMin=0;

  for (int i = 1; i < DS; i++) {
    dataBuff[i-1]=dataBuff[i];
    if(dataBuff[i]>bufMax)
      bufMax=dataBuff[i];
    if(dataBuff[i]<bufMin)
      bufMin=dataBuff[i];
  }

  dataBuff[DS-1] = ADConverter::voltage(ADConverter::result(true))/1000.0;
  if(bufMax < (-1*bufMin))
    bufMax=-1*bufMin;
  if(bufMax < 5)
    bufMax=5;
}

void wavePlot() {                    // 配列の値に基づきデーターをプロット
  long y,y0;

  for (int x = 1; x < DS; x++) {
    y0 = map(dataBuff[x-1], -1.0*bufMax, bufMax, 63,3); // プロット座標へ変換
    y  = map(dataBuff[x]  , -1.0*bufMax, bufMax, 63,3); // プロット座標へ変換
    display.drawLine(x*(120.0/DS)+4,y0,x*(120.0/DS)+4+1*(120.0/DS),y,WHITE);
  }

  display.setCursor(0,0);
  display.printf("Max:%d",bufMax);
  display.setCursor(80,0);
  display.printf("val=%d",dataBuff[DS-1]);
}