STM32G031でぞくに言うアナログサーボのデジタルシリアル化(サーボ側編)(RS-485)(その2)(数珠繋)


x まだ試していない　確認済み2022/5/15 17:04
x OBでリセットをリセットオンリーがわかる人むけ
x 書き込み器のリセット改造または、リセット接続を必ずしてください。

目的
前作の洗練化


いちお、仕様


ローレベル関数の共通化

32ビット
data = rs485packet_receive(0xc0); //ADD 0xc0 re(0x40)

下位8ビット有効　シンクロ(同期)が速い　戻りは、int
data = rs485packet_receive8(0xc0); //ADD 0xc0 re(0x40)

さらに下位関数 0が32ビット　1が下位8ビット
data = rs485packet_receive_io(0xc0,1); //ADD 0xc0 re(0x40)

直前の受信成功の有無　0失敗　0以外成功
re_status = rs485packet_receive_status();



なまえは、ser_500kbps_servo_S_031_v2とする

1 500bps RX
2 VDD
3 GND
4 リセットオンリー

8 SWD SWCL
7 SWD SWDA
6 デバッグ用ソフトウェアシリアル
5 PWM アナログサーボ信号 400uS-1400uS-2400uS 計算しやすい為にセンターずれ





![o_con429.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/09ea609a-2771-31da-6975-97045543968f.jpeg)



![o_con435.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/05484c57-6d54-a4d4-0251-97b85f884ecd.jpeg)



![o_con444.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/768112da-e40f-cc69-ce85-74f25759b735.jpeg)


![o_con445.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/47e05cbd-1661-c628-7bce-16a7222bc523.jpeg)



いろいろ
なんか仕様を書いている段階でどんどんアクセスがカウントアップされていく
特になにもないけど
ためにならない話、ちょつと疲れたアイス食ってくるわー2022/5/15 11:59
完成　めし行ってくるわ2022/5/15 17:05
記事を書いてる途中で見た人は、俺が考えた最強の仕様でお腹いっぱいになったのか?
RS485パケットねたは、複雑すぎたかもしれない。
ラジコンタイプのロボットは、サーボ信号→シリアル　または、　
シリアル→サーボ信号くらいの方がつかいやすいかも
ロボットコンテストだと受信機から出てきたアナログサーボ信号を
独自の機構に直接繋ぎたいという需要
マイコンのPWM(タイマー)が足りずアナログサーボを繋げたい需要
ラジコンのRCヘリまたは、ロボットのアナログサーボ用のプロポて
売っているのか?

50Hz＝アナログサーボ
150Hz＝デジタルサーボ、(NOR)、(S−FHSS)

デジタルサーボて名前だけでアナログじゃないか
シリアルタイプは、デジタルシリアルサーボなのか
なんかわかりずらい
シリアルサーボは、ロボットサーボなのか
いきなり、ちょつと飛ばしすぎた。

アクセスの集計を見ているとソフト関係がよくアクセスされるので
赤外線距離センサーのRS485パケット化を優先するか?
ハードの方が優先される傾向が強いからな!!


天から降って来るの待ち
「プログラム」は、天から降って来るものです。(笑い)(笑い)


プログラム


```c++


//ser_500kps_servo_031_3

#include <Arduino.h>


//サーボID 複数使う場合は、別のIDにしてください。
#define SERVO_ID   (0)


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

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


//プロトタイプ宣言
//32ビット
int rs485packet_receive(int id); //ADD 0xc0 re(0x40)

//下位8ビット有効　シンクロ(同期)が速い　戻りは、int
int rs485packet_receive8(int id); //ADD 0xc0 re(0x40)

//さらに下位関数 0が32ビット　1が下位8ビット
int rs485packet_receive_io(int id, int final8); //ADD 0xc0 re(0x40)


#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 pp;
  int re_status;

  //サーボの値を受信する　失敗は、_statusで読み取りる
  pp = rs485packet_receive8(0x10 + SERVO_ID); //ID 0
  //直前の受信成功の有無　0失敗　0以外成功
  re_status = rs485packet_receive_status();

  //デバッグ出力　受信した値の表示
  String thisString;
  thisString = String(re_status);
  pc_printf((char *)thisString.c_str());
  pc_printf(",");
  if ( re_status != 0 ) {
    thisString = String(pp);
    pc_printf((char *)thisString.c_str());
    //pc_printf("\r\n");
  }
  pc_printf("\r\n");

  if ( re_status != 0 ) {
    analogWrite(DD, 1310 + (26 * pp) );   // analogRead values go from 0
                                          // to 4095, pwmWrite values
                                          // from 0 to 65535, so scale roughly
  }//endif

}//loop


//32ビット ex ADD 0xc0 re(0x40)
int rs485packet_receive(int id) {

  int ret = rs485packet_receive_io(id, 0);

  return (ret);

}//rs485packet_receive


//下位8ビット有効　シンクロ(同期)が速い　戻りは、int  ex ADD 0xc0  re(0x40)
int rs485packet_receive8(int id) {

  int ret = rs485packet_receive_io(id, 1);

  return (ret);

}


//直前のパケットの読み取り失敗の有無
int re_status = 0;
int rs485packet_receive_status() {

  return (re_status);

}//rs485packet_receive_status


//さらに下位関数 0が32ビット　1が下位8ビット ex ADD 0xc0  re(0x40)
int rs485packet_receive_io(int id, int final8) {

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

  re_status = 0; //読み取り失敗にセット

  while (1) {

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

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

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

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

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

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

    //第七バイト目
    //チェックサム
    x = (char)ch_in_key();
    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] = x;
    //チェックサムの処理　八バイト目はFFで固定　チェックサム自身は、00
    if (x != (chk & 0xff) ) break;

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

    //オールクリア OK
    re_status = 1; //読み取り成功

    break;

  }//while

  pp = 0;
  if ( re_status != 0 ) {
    pp =      read_record[3 - 1];
    pp = pp << 8;
    pp = pp + read_record[4 - 1];
    pp = pp << 8;
    pp = pp + read_record[5 - 1];
    pp = pp << 8;
    pp = pp + read_record[6 - 1];
  }//endif

  //リターン
  return (pp);

} //rs485packet_receive_io



```