STM32G031とマイコン応用I2C超音波距離センサーで遊ぶ(タイマー割り込み)(LPF)



目的
オリジナルI2C超音波距離センサーをつかい
任意の時間でローパスフィルター(LPF)を掛けた値の表示


![o_con377.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/8a29cfad-e47f-8bab-e847-03d209aed5e9.jpeg)



![o_con346.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/ca6f60fe-d577-2fe1-3bf6-73e4cddb1479.jpeg)




https://qiita.com/caa45040/items/b74c0e26e768fdf750a3

細かい修正



```c++



//i2c_master_interrupt_HC_SR04_031_1

#include <Arduino.h>
#include <Wire.h>

//150 000
//#define LOOP_INTERVAL 150000
//500 000
#define LOOP_INTERVAL 500000

//タイマー割り込みの設定
HardwareTimer *timer2 = new HardwareTimer (TIM2);


//10の割り算 0から1028までは、正しい。主に0から999
#define DIV10(n) ((n*205)>>11)


#define in7      PA0  // 4pin
#define DW   digitalWrite
#define UART_DELAY 102   //  9600bps ok 031

//仮想シリアルへの一文字出力 9600bps
int pc_putc(char ch) {
  DW(in7, HIGH);

  DW(in7, LOW);//START
  delayMicroseconds(UART_DELAY);

  for (int ii = 0; ii < 8; ii++) {
    DW(in7, (ch >> ii) & 1  );
    delayMicroseconds(UART_DELAY);
  }//for

  DW(in7, HIGH);//Stop
  delayMicroseconds(UART_DELAY);

  return (0);
}//pc_putc


//文字列の表示
int pc_printf(char *str1) {

  //文字の中身がゼロか
  while (*str1) {
    //一文字出力
    pc_putc(*str1 ++);
  } //while

  //戻り値
  return (0);
}//pc_printf


//移動平均用
int  h1, h2, h3;
int  p;
char in_l;

void intTimer(void) {

  int l = (int)in_l; //超音波距離センサーの値
  char data_read[8]; //バッファー

  //前の0を削る
  //  012  add
  // [123] data
  int yy;
  if      (l >= 100) {
    yy = 0;
  }
  else if (l >= 10)  {
    yy = 1;
  }
  else               {
    yy = 2;
  }

  //表示
  data_read[3] = 0;
  data_read[2] = '0' + (  l - (DIV10(l) * 10)  );  // '0'+(b%10)
  l = DIV10(l);
  data_read[1] = '0' + (  l - (DIV10(l) * 10)  );  // '0'+(b%10)
  data_read[0] = '0' +  DIV10(l);                  // '0'+(s/10)

  pc_printf("80,");

  pc_printf( ((char *)(data_read + yy )) ); //031

  pc_printf(",0");
  pc_printf("\r\n"); //リターン

}//intTimer


//初期化
void setup()
{

  //ポートをhiにする ソフトウェアシリアルの初期化
  pinMode(in7, OUTPUT);
  DW(in7, HIGH);

  //I2Cの初期化
  Wire.begin(PA12, PA11); //stm32g031

  //タイマー割り込み
  timer2->setOverflow(LOOP_INTERVAL, MICROSEC_FORMAT);       // 125ms
  timer2->attachInterrupt(intTimer);
  timer2->resume();

} //setup


//メインループ
void loop()
{

  char data_read[8]; //バッファー
  int  l; //距離
  unsigned char b = 200; //I2C超音波距離センサー値

  //I2C読み込み
  Wire.requestFrom(8, 1);

  while (Wire.available())  {   // 要求より短いデータが来る可能性あり
    b = Wire.read();       // 1バイトを受信
  }//while

  //レンジ圧縮の展開
  //140までは、mm
  //140からは、cm
  if ( b <= 139 ) {
    l = b + 60;
  } else {
    l = ((int)(b - 140 + 20)) * 10;
  }

  //移動平均
  p = (h1 + h2 + h3 + l) >> 2;
  h3 = h2;
  h2 = h1;
  h1 = l;
  in_l = (char)(p / 10);

  delay(20); // 20m秒の待ち

}//loop




```




修正前

```c++






//i2c_master_interrupt_HC_SR04_031_1


#include <Arduino.h>
#include <Wire.h>

//150 000
//#define LOOP_INTERVAL 150000
//500 000
#define LOOP_INTERVAL 500000
//#define BOARD_LED_PIN PA11

HardwareTimer *timer2 = new HardwareTimer (TIM2);


//10の割り算 0から1028までは、正しい。主に0から999
#define DIV10(n) ((n*205)>>11)

#define in7      PA0  // 4pin

#define DW   digitalWrite

#define UART_DELAY 102   //  9600bps ok 031


//仮想シリアルへの一文字出力 9600bps
int pc_putc(char ch) {

  DW(in7, HIGH);

  DW(in7, LOW);//START
  delayMicroseconds(UART_DELAY);

  for (int ii = 0; ii < 8; ii++) {
    DW(in7, (ch >> ii) & 1  );
    delayMicroseconds(UART_DELAY);
  }//for

  DW(in7, HIGH);//Stop
  delayMicroseconds(UART_DELAY);

  return (0);

}//pc_putc


//文字列の表示
int pc_printf(char *str1) {

  //文字の中身がゼロか
  while (*str1) {

    //一文字出力
    pc_putc(*str1 ++);

  } //while

  //戻り値
  return (0);

}//pc_printf


//初期化
void setup()
{

  //ポートをhiにする 初期化
  pinMode(in7, OUTPUT);
  DW(in7, HIGH);

  //I2Cの初期化
  Wire.begin(PA12, PA11); //stm32g031

  //タイマー割り込み
  timer2->setOverflow(LOOP_INTERVAL, MICROSEC_FORMAT);       // 125ms
  timer2->attachInterrupt(intTimer);
  timer2->resume();


} //setup


int  h1,h2,h3;
int  p;
char in_l;


//メインループ
void loop()
{

  char data_read[8]; //バッファー
  int  l;
  unsigned char b = 200;

  //読み込み
  Wire.requestFrom(8, 1);

  while(Wire.available())  {    // 要求より短いデータが来る可能性あり
    b = Wire.read();       // 1バイトを受信
  }//while

  if( b <= 139 ) {
    l = b + 60;
  } else {
    l = ((int)(b - 140 + 20)) * 10;
  }

  //移動平均
  p = (h1+h2+h3+l)>>2;
  h3 = h2;
  h2 = h1;
  h1 = l;
  in_l = (char)(p/10);

}//loop


void intTimer(void){

  int l = (int)in_l;
  char data_read[8]; //バッファー


  //前の0を削る
  //  012  add
  // [123] data
  int yy;
  if      (l >= 100) {yy = 0;}
  else if (l >= 10)  {yy = 1;}
  else               {yy = 2;}

  //表示
  data_read[3] = 0;
  data_read[2] = '0' + (  l - (DIV10(l) * 10)  );  // '0'+(b%10)
  l = DIV10(l);
  data_read[1] = '0' + (  l - (DIV10(l) * 10)  );  // '0'+(b%10)
  data_read[0] = '0' +  DIV10(l);                  // '0'+(s/10)

  pc_printf("80,");

  pc_printf( ((char *)(data_read + yy )) ); //031

  pc_printf(",0");
  pc_printf("\r\n");

  //delay(500); // 0.5秒の待ち

}//intTimer






```