0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

STM32L010と超音波距離センサーHC-SR04でソフトウェアシリアルバイナリ通信

Posted at

目的
I2Cだと約20cmから約30cmと伝送距離が短いので
シリアルを使い伝送距離(約2mから3m)を延ばす。

o_con386.jpg

STM32L010のスレーブ




//ser_slave_HC_SR04_010_1


#include "mbed.h"


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


DigitalOut TX(PA_2);
DigitalIn  RX(PA_3);

#define UART_DELAY 101 //  1/9600 98-105


//仮想シリアルへの一文字出力 9600bps
int pc_putc(char ch)
{
    TX=1;
    TX=0;//Start
    wait_us(UART_DELAY);

    for(int ii=0; ii<8; ii++) { //Data x 8
        TX=(ch>>ii)&1;
        wait_us(UART_DELAY);
    }; //for

    TX=1;//Stop
    wait_us(UART_DELAY);

    return(0);
} //pc_putc


#define HIGH 1
DigitalOut TRIG(PA_6);
DigitalIn  ECHO(PA_5);


//タイマーの設定
Timer t;

unsigned long times; //測定時間
int distance;        //長さ


//PA_5のオン時間をusで測る 今のところ引数は、無効
int pulseIn(int pin1,int pu1,int timeout1)
{

    t.reset();//タイマーの開始

    //timeout1 = 32000000;
    timeout1 = 100000;    //28ms
    //timeout1 = 1000;   //degbu

    //while(PA_5 == 0) {}

loop_s1:
    timeout1--;
    //                            5432109876543210
    if (     (~(GPIOA->IDR))  & 0b0000000000100000     ) {
        if ( timeout1 ) {
            goto loop_s1;
        }
    }


    int sd = t.read_us();//測定開始

    //timeout1 = 32000000;
    timeout1 = 100000;     //28ms
    //timeout1 = 1000;   //degbu

    //while(PA_5 != 0) {}

loop_in1:
    timeout1--;
    //                      5432109876543210
    if (   (GPIOA->IDR) & 0b0000000000100000   ) {
        if( timeout1 ) {
            goto loop_in1;
        }
    }


    return(t.read_us()-sd);//測定終了

}//pulseIn


unsigned char b=200; //マスターに返す値

//プロトタイプ宣言
void rx_Event();


//メインルーチン
int main()
{

    //タイマーの開始
    t.start();

    TX=1; //ポートの初期化

    //GPIOの初期化
    TRIG = 0;


    int input_bk;
    int input;

    //無限ループ
    while(1) {


        //開始信号の入力
        input = RX;

        //エッジ検出 信号が変わる
        //立ち上がり、立下りの検出
        if (input != input_bk) {

            //立下り
            if ( input == 0 ) {
                wait_ms(2); //空読み時間

                //b = '0';
                //putcNS(b);
                rx_Event();
            }//end if

        }//end if

        //信号の保存
        input_bk = input;

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

    }//while

}//main


void rx_Event()
{

    //ソフトウェアシリアルから距離を出力
    pc_putc(b);

    /*
        //I2Cスレーブの送信データの表示 num debug
        int d = b; //buf[0];
        //int d = b; //+ 60;
        //int d = ir_length;
        char data_read[4]; //バッファーの定義
        data_read[3] = 0;
        data_read[2] = '0' + (  d - (DIV10(d) * 10)  );  // '0'+(d%10)
        d = DIV10(d);
        data_read[1] = '0' + (  d - (DIV10(d) * 10)  );  // '0'+(d%10)
        data_read[0] = '0' +  DIV10(d);                  // '0'+(d/10)
        pc_putc(data_read[0]);
        pc_putc(data_read[1]);
        pc_putc(data_read[2]);
        pc_putc('\r');
        pc_putc('\n');
    */


    // 超音波を発生させる
    TRIG=1;
    wait_us(10);
    TRIG=0;

    // 超音波を受け取る
    times = pulseIn( 5, HIGH,2000000);

    //times = (unsigned long)7700/2; //debug
    //times = 1177;//debug 1ms 20.0cm
    //times = 942;//debug 1ms 16.0cm



    //distance = (int)(times * 0.017);
    distance = (int)((times * ((unsigned long)(17))) / 100);




    //レンジ圧縮をして8ビット(256)に収める
    //60mm から 200mmまでは、1mm単位
    //60mm = 0 , 200mm = 140
    //200mm から 800mmまでは、1cm単位
    //200mm =140 ,  800mm = 200


    if ( distance <= 199 ) {

        b = distance - 60;

    } else {

        b = (unsigned char)(   DIV10(distance)-20+140 );

    }//endif


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

}//rx_Event


//容量削減
void error(const char* format, ...) {}






Arduino UNOのマスター





#include <Arduino.h>

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX


//初期化
void setup()
{

  //シリアルポートの初期化
  Serial.begin(9600);

  //ソフトウェアシリアルの初期化
  mySerial.begin(9600);

} //setup


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

  int  l; //距離
  unsigned char b = 200;

  //読み込み
  mySerial.print("S");delay(5); //トリガーを投げる
  while( mySerial.available() ){
    //Serial.println( mySerial.available() );//debug
    b = mySerial.read();//受信
    //Serial.println( b );//debug
  }//while  
  if( b <= 0   ) b=0;
  if( b >= 200 ) b=200;

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

  Serial.print("800,");

  Serial.print( l ); //UNO

  Serial.print(",0");
  Serial.println(" ");

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

} //loop





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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?