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 1 year has passed since last update.

STM32L010のI2CスレーブモードでGP2Y0A21YK(赤外線距離センサー)の値をマスターで受信する。

Last updated at Posted at 2022-04-24

目的
I2Cのテスト
距離センサーのI2C化
I2C間通信の応用
赤外線距離センターを使い距離を測る。

o_con349.jpg

忙しい人よう

バイナリー

スレーブのプログラム

mbed2リビジョン130




//i2c_slave_ir_length_010_1


#include "mbed.h"


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

/*
DigitalOut TX(PB_1);

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

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

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

    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; //マスターに返す値

//I2Cの初期化
I2CSlave slave(PA_10, PA_9); //010

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

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


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

    char buf[10];//I2Cバッファー

    //I2Cスレーブのアドレスの設定
    slave.address(0x10);

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

        //I2Cの状態の読み出し(ポーリング)
        while(  slave.receive()  == I2CSlave::ReadAddressed   ) {};


        buf[0] = b;

        //I2Cマスターに送信する
        slave.write(buf,1);

/*

        //I2Cスレーブの送信データの表示 num debug
        int d = b; //buf[0];
        char data_read[3]; //バッファーの定義
        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');
*/

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

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

        ir_length = ir_len_i(Voltage);


        if ( ir_length <= 199 ) {

            b = ir_length - 60;

        } else {

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

        }


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

    }//while

}//main


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






マスターのプログラム

mbed2リビジョン125



//i2c_master_ir_length_031_1

#include "mbed.h"

//I2C i2c(I2C_SDA, I2C_SCL); //767
//I2C i2c(dp5, dp27); //1114
I2C i2c(PA_10, PA_9); //010


//Serial pc(USBTX, USBRX); // tx, rx
//Serial pc(SERIAL_TX, SERIAL_RX); //767
RawSerial pc(PA_2, PA_3); //010

//#define S5851A 0x48
#define ADDR        (0x10)   //  address

int main() {

    char data_read[8]; //バッファー

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

        //dataの読み込み
        i2c.read(ADDR, data_read,1,false);

        //データの保存
        int b =  data_read[0]; //dataの転記
        if(b >= 200) {b = 200;}
        if(b <= 0)   {b = 0;  }
        
        
        //レンジ圧縮で140でレンジ切り替え
        int l;
        if( b <= 139 ) {
            l = b + 60;
        } else {
            l = ((int)(b - 140 + 20)) * 10;
        }  
        

        //画面に表示
        //pc.printf("Read : %x\r\n",l);
        //pc.printf("Read : %d\r\n",l);
        pc.printf("%d\r\n",l);

        //1/100秒待つ
        wait_ms(10);

    }//while

}//main

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




関連 Arduinoのマスタープログラム




//i2c_master_HC_SR04_UNO_1

//インクルド
#include <Arduino.h>
#include <Wire.h>

//初期化
void setup()
{

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

  //I2Cの初期化
  Wire.begin(); //UNO

} //setup


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

  int  l;                //距離
  unsigned char b = 200; //レンジ圧縮の値

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

  //レンジ圧縮をして8ビット(256)に収める
  //60mm から 200mmまでは、1mm単位
  //60mm = 0 , 200mm = 140
  //200mm から 800mmまでは、1cm単位
  //200mm =140 ,  800mm = 200
  if( b <= 139 ) {
    l = b + 60;
  } else {
    l = ((int)(b - 140 + 20)) * 10;
  }//endif

  //距離の表示
  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?