STM32G031でRS-485パケットでアナログサーボを動かす(サーボー受信(その1



x まだ試していない　確認ずみ2022/5/13 9:19

目的
STM32G031で数珠繋ぎで複数サーボを動かす
とごまで行けるかわからないがやってみる
1話にならずに複数話になる。

なんとなく、サーボにかんしては、順次処理形式で行けそう。
データ4バイトの内3バイトが0固定だからヘッダーの代わりになる
一番難しいシンクロ(同期)が何とかなりそう
いがいに早くできそう

PWM!!の確認わすれていたわ 2022/5/13 9:20 制作済み

ちょっと気分転換でPWMを作ろう


デバッグの為に一旦、バイナリをテキストの文字にする

00 10 00 00  00 12 7B FF

0  1   0  0   0  2  7 9

とする。





![o_con429.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/d06cd6bd-980a-9278-e64e-84193c8d73c9.jpeg)



![o_con433.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/6fb7e9f3-33d0-6a4e-a938-9476f4fc94e8.jpeg)


![o_con434.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a31790d2-63b6-4987-9d53-1467d152f2e2.jpeg)



![o_con435.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/8c9cf3aa-5c22-b7a8-b898-a40f9ef3fbe7.jpeg)



いろいろ
RS485のバードは、別立てにするか?




PWMとチェックサムを追加　完成や!! バグppが転記されていない 修正済み


```c++



//ser_500kps_servo_031_3

#include <Arduino.h>

#define DD PA11    // potentiometer connected to analog pin x

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

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

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

/*
  #define  header   '0'
  #define  address  '1'
  #define  data1    '0'
  #define  data2    '0'

  #define  data3    '0'
  #define  data4    '2'
  #define  Checksum '7'
  #define  footer   '9'
*/

#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


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

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

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

  //PWMの初期化
  pinMode(DD, OUTPUT);   // sets the LED pin as output
  analogWriteFrequency(50);
  analogWriteResolution(16);

} //setup


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

  int ii;           //カウンター
  int pp;           //ポジション
  char out_buff[8]; //バッファー
  int chk;             //チェックサム
  char read_record[8];
  char x;          //一時領域

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


  pc_printf("<ST>");

  while (1) {

    //第一バイト目
    //ヘッダー

    x = (char)ch_in_key();
    read_record[1 - 1] = 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);

    //1
    if (x != header ) break;


    //第二バイト目
    //アドレス

    x = (char)ch_in_key();
    read_record[2 - 1] = 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);

    if (x != address ) break;


    //第三バイト目
    //データの1

    x = (char)ch_in_key();
    read_record[3 - 1] = 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);

    //3
    if (x != data1 ) break;


    //第四バイト目
    //データの2

    x = (char)ch_in_key();
    read_record[4 - 1] = 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);

    //4
    if (x != data2 ) break;

    //第五バイト目
    //データの3

    x = (char)ch_in_key();
    read_record[5 - 1] = 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);

    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;

    //ヘキサに値を設定
    // 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);

    //チェックサムの計算
    //Checksum
    //read_record[1 - 1] = 0x00;
    //read_record[2 - 1] = 0x10;
    //read_record[3 - 1] = 0x00;
    //read_record[4 - 1] = 0x00;

    //read_record[5 - 1] = 0x00;
    //read_record[6 - 1] = 0x12;
    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;

    //  out_buff[0] = '-';
    //  out_buff[1] = c_hex[(chk >> 4) & 0x0f];
    //  out_buff[2] = c_hex[chk & 0x0f];
    //  out_buff[3] = '-';
    //  out_buff[4] = 0x00;
    //  pc_printf(out_buff);

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


    //第八バイト目
    //フッター

    x = (char)ch_in_key();
    read_record[8 - 1] = 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);

    if (x !=  footer ) break;

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



    analogWrite(DD, 1310 + (26 * pp) );   // analogRead values go from 0
                                          // to 4095, pwmWrite values
                                          // from 0 to 65535, so scale roughly





    break;

  }//while

  //pc_printf("<ST>");

  //delay(1000);

} //loop





```



送信プログラムからの入力

![o_con430.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/094980e9-6cea-f6cd-4b69-9672a02cd52d.jpeg)




一時的に信号を手入力


![o_con428.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/73a16e22-a02d-b96c-0353-f607d6eabc66.jpeg)



```c++



//ser_500kbps_mon_031_1

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

#include <Arduino.h>




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

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

/*
#define  header   '0'
#define  address  '1'
#define  data1    '0'
#define  data2    '0'

#define  data3    '0'
#define  data4    '2'
#define  Checksum '7'
#define  footer   '9'
*/





#define DW   digitalWrite
#define TX1        PA11   // 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


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

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

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

} //setup


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

  int ii;           //カウンター
  char out_buff[8]; //バッファー
  char read_record[8];
  char x;          //一時領域

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


  pc_printf("<ST>");

while(1){


//第一バイト目

  x = (char)ch_in_key();



  //ヘキサに値を設定
  // 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);

  //1
  if(x != header ) break;


//第二バイト目

  x = (char)ch_in_key();



  //ヘキサに値を設定
  // 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);

if(x != address ) break;


//第三バイト目

  x = (char)ch_in_key();



  //ヘキサに値を設定
  // 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);

//3
if(x != data1 ) break;


//第四バイト目

  x = (char)ch_in_key();



  //ヘキサに値を設定
  // 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);

//4
if(x != data2 ) break;


//第五バイト目

  x = (char)ch_in_key();



  //ヘキサに値を設定
  // 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);


if(x != data3 ) break;


//第六バイト目

  x = (char)ch_in_key();



  //ヘキサに値を設定
  // 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();



  //ヘキサに値を設定
  // 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);


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


//第八バイト目

  x = (char)ch_in_key();



  //ヘキサに値を設定
  // 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);

if(x !=  footer ) break;

  pc_printf("<OK>");
  pc_printf("\r\n");

  break;

}//while

  //pc_printf("<ST>");

  //delay(1000);

} //loop




```







こんなもんだ

一時的に手入力用


```c++


//ser_500kbps_mon_031_1

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

#include <Arduino.h>



/*
#define  header   0x00;
#define  address  0x10;
#define  data1    0x00;
#define  data2    0x00;

#define  data3    0x00;
#define  data4    0x12;
#define  Checksum 0x00;
#define  footer   0xff;
*/

#define  header   '0'
#define  address  '1'
#define  data1    '0'
#define  data2    '0'

#define  data3    '0'
#define  data4    '2'
#define  Checksum '7'
#define  footer   '9'






#define DW   digitalWrite
#define TX1        PA11   // 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


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

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

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

} //setup


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

  int ii;           //カウンター
  char out_buff[8]; //バッファー
  char x;          //一時領域

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

while(1){


//第一バイト目

  x = (char)ch_in_key();



  //ヘキサに値を設定
  // 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);

  //1
  if(x != header ) break;


//第二バイト目

  x = (char)ch_in_key();



  //ヘキサに値を設定
  // 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);

if(x != address ) break;


//第三バイト目

  x = (char)ch_in_key();



  //ヘキサに値を設定
  // 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);

//3
if(x != data1 ) break;


//第四バイト目

  x = (char)ch_in_key();



  //ヘキサに値を設定
  // 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);

//4
if(x != data2 ) break;


//第五バイト目

  x = (char)ch_in_key();



  //ヘキサに値を設定
  // 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);


if(x != data3 ) break;


//第六バイト目

  x = (char)ch_in_key();



  //ヘキサに値を設定
  // 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();



  //ヘキサに値を設定
  // 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);


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


//第八バイト目

  x = (char)ch_in_key();



  //ヘキサに値を設定
  // 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);

if(x !=  footer ) break;

  pc_printf("<OK>");
  pc_printf("\r\n");

  break;

}//while

  pc_printf("<ST>");

  delay(1000);

} //loop


```