STM32G031でRS-485パケットで赤外線距離センサーの値を読み込みたい(マスター編



x まだ試していない 確認済み　2022/5/17 17:29

目的
RS-485パケットで上り下りの実現
複数話になる
どこまで行けるかわからないが作ってみよう

仕様
●センサーに読み取り開始パケットを送る
●受信をまつ　タイムアウトあり? (タイムアウトは、まだない)


[H][add][data1][data2][data3][data4][chk_sum][F]

[00][50][00][00][00][00][4F][FF]


送信だけチェックしたらOK


![o_con446.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/c66a57b1-080a-d153-5874-e39a685a6d08.jpeg)


![o_con449.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/7a14ae17-356e-c96b-0f8d-f63bf390f116.jpeg)


![o_con450.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/8e5f5430-187e-6fa4-483f-10c0e81bd9e2.jpeg)



```c++


//ser_500kbps_ir_length_M_031_1

// tx PA14(PB6) 8PIN
// rx PC14(PB7) 1PIN

#include <Arduino.h>


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


#define  header   0x00
#define  address  0xC0
#define  data1    0x00
#define  data2    0x00

#define  data3    0x00
#define  data4    0x00
#define  Checksum 0x00
#define  footer   0xff


#define DW   digitalWrite
#define TX1        PA12   // 4pin
#define UART_DELAY 106  // 002-110 9600bps ok 031

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

  DW(TX1, LOW);//START
  delayMicroseconds(UART_DELAY); //START BIT WAIT

  for (int ii = 0; ii < 8; ii++) {
    DW(TX1, (ch >> ii) & 1  );
    delayMicroseconds(UART_DELAY); //DATA 1-8BIT WAIT
  }//for

  DW(TX1, HIGH);//Stop
  delayMicroseconds(UART_DELAY); //StOP BIT WAIT

}//pc_putc


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

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

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

  } //while

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


void ir_length_send(char id){

  int ii;           //カウンター
  char out_buff[8]; //バッファー

  //バケットに値を設定
  // packet move
  out_buff[1 - 1] = 0x00; //header
  out_buff[2 - 1] = 0x40+id; //address
  out_buff[3 - 1] = 0x00; //data1  zero Fixed
  out_buff[4 - 1] = 0x00; //data2  zero Fixed

  out_buff[5 - 1] = 0x00; //data3  zero Fixed
  out_buff[6 - 1] = 0x00; //data4  zero Fixed
  out_buff[7 - 1] = 0x00; //Checksum
  out_buff[8 - 1] = 0xff; //footer

  //チェックサムの計算
  //Checksum
  int chk = 0;
  for (ii = 0; ii < 8; ii++) {
    chk = chk + out_buff[ii];
  }//for
  out_buff[7 - 1] = chk & 0xff;

  //送信処理
  //send 8 byte
  delay(1);
  for (ii = 0; ii < 8; ii++) {
    Serial.write(out_buff[ii]);
  }//for
  delay(1);

} //pc_putc


int u_key;      // 受信データを格納するchar型の変数
int ch_in_key() {

  // 受信データがあった時だけ、処理を行う
  while (!Serial.available()) {}      // 受信データがあるか？
  u_key = Serial.read();            // 1文字だけ読み込む

  return (u_key);
}


//初期化処理
void setup() {

  delay(3000); //not Delete

  Serial.begin( 500000 ); // シリアル通信の速度を500000bpsにする。

  //TXポートの初期化
  pinMode(TX1, OUTPUT);
  DW(TX1, HIGH);

  //pc_printf("<STooooooooooooooooooooo>");
    pc_printf("<ST>                     ");


} //setup


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

  ir_length_send(16); //ID 16

  delay(500);

  //受信
  int l = ir_length_receive(16); //ID 16

  //表示
  //int l = 200; //debug
  char out_buff[8];
  out_buff[3] = 0;
  out_buff[2] = '0' + (  l - (DIV10(l) * 10)  );  // '0'+(b%10)
  l = DIV10(l);
  out_buff[1] = '0' + (  l - (DIV10(l) * 10)  );  // '0'+(b%10)
  out_buff[0] = '0' +  DIV10(l);                  // '0'+(s/10)

  //送信処理
  //send 8 byte
  pc_printf(out_buff);
  pc_printf("\r\n");

  delay(1000);

}//loop


int ir_length_receive(char id) {

  int ii;           //カウンター
  int pp;           //ポジション
  char out_buff[8]; //バッファー
  int chk;             //チェックサム
  char read_record[8];
  char x;          //一時領域
  char b = 200;    //レンジ圧縮した距離
  int  l;          //距離

  //  char c_hex[] = {
  //    '0', '1', '2', '3', '4', '5', '6', '7',
  //    '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
  //  };

  b = 200;

  //pc_printf("<ST>");

  while (1) {

    //第一バイト目
    //ヘッダー
    x = (char)ch_in_key();
    read_record[1 - 1] = x;
    if (x != header ) break;

    //第二バイト目
    //アドレス
    x = (char)ch_in_key();
    read_record[2 - 1] = x;
    if (x != (0xc0 + id) ) break;

    //第三バイト目
    //データの1
    x = (char)ch_in_key();
    read_record[3 - 1] = x;
    if (x != data1 ) break;

    //第四バイト目
    //データの2
    x = (char)ch_in_key();
    read_record[4 - 1] = x;
    if (x != data2 ) break;

    //第五バイト目
    //データの3
    x = (char)ch_in_key();
    read_record[5 - 1] = x;
    if (x != data3 ) break;

    //第六バイト目
    //データの4
    x = (char)ch_in_key();
    read_record[6 - 1] = x;
    pp = x;

    //    //ヘキサに値を設定
    //    // packet move
    //    out_buff[0] = '[';
    //    out_buff[1] = c_hex[(x >> 4) & 0x0f];
    //    out_buff[2] = c_hex[x & 0x0f];
    //    out_buff[3] = ']';
    //    out_buff[4] = 0x00;
    //    //送信処理
    //    //send 8 byte
    //    pc_printf(out_buff);

    //第七バイト目
    //チェックサム
    x = (char)ch_in_key();
    read_record[7 - 1] = x;

    //チェックサムの計算
    //Checksum
    read_record[7 - 1] = 0x00;
    read_record[8 - 1] = 0xff;
    chk = 0;
    for (ii = 0; ii < 8; ii++) {
      chk = chk + read_record[ii];
    }//for
    read_record[7 - 1] = chk & 0xff;

    //チェックサムの処理　八バイト目はFFで固定　チェックサム自身は、00
    if (x != (chk & 0xff) ) break;

    //第八バイト目
    //フッター
    x = (char)ch_in_key();
    read_record[8 - 1] = x;
    if (x !=  footer ) break;

    //オールクリア
    //pc_printf("<OK>");
    //pc_printf("\r\n");

    b = pp;

    break;

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

  return (l);

} //loop



```