LoginSignup
0
0

More than 1 year has passed since last update.

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

Last updated at Posted at 2022-05-01

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

o_con377.jpg

o_con346.jpg

細かい修正




//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




修正前







//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






0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0