LoginSignup
0
0

More than 1 year has passed since last update.

STM32L010と赤外線距離センサーGP2Y0A21YKでソフトウェアシリアルバイナリ通信

Posted at

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

o_con385.jpg

STM32L010のスレーブ




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


//80-20
unsigned char qq[] = {
    80, 78, 77, 76, 75, 75, 74, 73, 72, 71,
    70, 69, 68, 68, 67, 66, 65, 65, 64, 63,
    63, 62, 61, 61, 60, 60, 59, 58, 58, 57,
    57, 56, 56, 55, 55, 54, 54, 53, 53, 52,
    52, 51, 51, 50, 50, 50, 49, 49, 48, 48,
    47, 47, 47, 46, 46, 46, 45, 45, 45, 44,
    44, 44, 43, 43, 43, 42, 42, 42, 41, 41,
    41, 41, 40, 40, 40, 40, 39, 39, 39, 38,
    38, 38, 38, 37, 37, 37, 37, 37, 36, 36,
    36, 36, 35, 35, 35, 35, 35, 34, 34, 34,
    34, 34, 33, 33, 33, 33, 33, 32, 32, 32,
    32, 32, 32, 31, 31, 31, 31, 31, 31, 30,
    30, 30, 30, 30, 30, 30, 29, 29, 29, 29,
    29, 29, 28, 28, 28, 28, 28, 28, 28, 28,
    27, 27, 27, 27, 27, 27, 27, 27, 26, 26,
    26, 26, 26, 26, 26, 26, 25, 25, 25, 25,
    25, 25, 25, 25, 25, 25, 24, 24, 24, 24,
    24, 24, 24, 24, 24, 24, 23, 23, 23, 23,
    23, 23, 23, 23, 23, 23, 22, 22, 22, 22,
    22, 22, 22, 22, 22, 22, 22, 22, 21, 21,
    21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
    21, 20, 20, 20, 20, 20, 20, 20, 20, 20,
    20, 20, 20, 20, 20, 20
};

//20-10
unsigned char pp[] = {
    200, 199, 198, 197, 196, 196, 195, 194, 193, 193,
    192, 191, 190, 190, 189, 188, 187, 187, 186, 185,
    185, 184, 183, 183, 182, 181, 181, 180, 179, 179,
    178, 177, 177, 176, 176, 175, 174, 174, 173, 173,
    172, 171, 171, 170, 170, 169, 168, 168, 167, 167,
    166, 166, 165, 165, 164, 163, 163, 162, 162, 161,
    161, 160, 160, 159, 159, 158, 158, 157, 157, 156,
    156, 155, 155, 154, 154, 153, 153, 152, 152, 151,
    151, 151, 150, 150, 149, 149, 148, 148, 147, 147,
    147, 146, 146, 145, 145, 144, 144, 144, 143, 143,
    142, 142, 142, 141, 141, 140, 140, 140, 139, 139,
    138, 138, 138, 137, 137, 136, 136, 136, 135, 135,
    135, 134, 134, 134, 133, 133, 132, 132, 132, 131,
    131, 131, 130, 130, 130, 129, 129, 129, 128, 128,
    128, 127, 127, 127, 126, 126, 126, 125, 125, 125,
    125, 124, 124, 124, 123, 123, 123, 122, 122, 122,
    121, 121, 121, 121, 120, 120, 120, 119, 119, 119,
    119, 118, 118, 118, 117, 117, 117, 117, 116, 116,
    116, 116, 115, 115, 115, 114, 114, 114, 114, 113,
    113, 113, 113, 112, 112, 112, 112, 111, 111, 111,
    111, 110, 110, 110, 110, 109, 109, 109, 109, 108,
    108, 108, 108, 107, 107, 107, 107, 107, 106, 106,
    106, 106, 105, 105, 105, 105, 105, 104, 104, 104,
    104, 103, 103, 103, 103, 103, 102, 102, 102, 102,
    102, 101, 101, 101, 101, 101, 100, 100, 100, 100,
    100
};

//10-6
unsigned char oo[] = {
    100, 99, 98, 98, 97, 97, 96, 96, 95, 95,
    94, 94, 93, 93, 92, 92, 91, 91, 90, 90,
    90, 89, 89, 88, 88, 87, 87, 86, 86, 86,
    85, 85, 84, 84, 84, 83, 83, 82, 82, 82,
    81, 81, 81, 80, 80, 80, 79, 79, 78, 78,
    77, 77, 76, 76, 75, 75, 74, 74, 74, 73,
    73, 72, 72, 71, 71, 71, 70, 70, 69, 69,
    68, 67, 66, 66, 65, 64, 63, 63, 62, 61,
    61, 60, 60
};


//赤外線距離センサー(GP2Y0A21YK)の電圧から距離を求める。
//Voltage //電圧
int ir_len_i(int Voltage)
{

    int ir_length;   //長さ

    if (Voltage >= 0    && Voltage <= 400 ) {
        return (800);
    }
    if (Voltage >= 3120 && Voltage <= 5000) {
        return (60);
    }

    if        (Voltage >= 400 && Voltage <= 1300 ) { //80-20

        ir_length = (int)qq[(Voltage - 400) >> 2];
        ir_length = ir_length * 10;

    } else if (Voltage >= 1300 && Voltage <= 2300 ) { //20-10

        ir_length = (int)pp[(Voltage - 1300) >> 2];

    } else if (Voltage >= 2300 && Voltage <= 3120  ) { //10-6

        //ir_length = (int)oo[(Voltage - 2300) / 10];
        ir_length = (int)oo[  ((Voltage - 2300)*205)>>11 ]; //10の割り算

    }//end if

    //戻り値
    return (ir_length);

} //ir_le_i


//アナログ入力の設定
AnalogIn adc_vbat(A3); //PA_4

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

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


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

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

    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');
*/

    int sensorValue; //センサーの読み取り値
    int Voltage;     //電圧
    int ir_length;   //長さ

    //アナログ値の読み込み  0から4096
    sensorValue = (adc_vbat.read_u16()>>4);
    //sensorValue = 1024;
    //sensorValue = 2854; // debug 100mm

    //アナログ値を電圧に変換
    Voltage = (sensorValue * 3300) >> 12; //stm32 (s*3300)/4096
    //Voltage = 2300; //debug 100mm

    ir_length = ir_len_i(Voltage);


    if ( ir_length <= 199 ) {

        b = ir_length - 60;

    } else {

        b = (unsigned char)(   DIV10(ir_length)-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