STM32G031でMAVLinkのCRCで遊ぶ


x 動作確認済み2022/5/20 0:58

X 株式会社センシンロボティクスの記事を非営利、研究調査目的で引用します。


目的
MAVLinkは、今時流行りのドローンの高度や位置のログを送る
プロトコルらしい
持ってないけど
MAVLinkのパケット構造は、簡単だけど
CRCの計算がいまだかって理解できないがソースがあるので適当にぱくって
都合よくマイコンに実装する
なんか、送信、受信でCRC_EXTRAと称する
固定化された暗号キーみたいなが必要になるらしい
ラジコンのマニュアルに00とか124とか書いてある物が必要らしいが
適当に124とする。
読める、読めるぞ(ラピタふう)


dfを除いたヘッダー部分が43558になれば当たりらしい
初期値値は、X25_INIT_CRC 0xffff

32 00 00 ca 01 01 7a e6 00


0x0e,0x04,0x19... が　63626になっていれば、正しいらしい


[EF]13395
[D7]35224

たぶんEFが間違いでD7が正しい?


![o_con464.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/7e007008-9ebf-670e-d5a1-a3eb6a9bb678.jpeg)




いろいろ
ほぼ、ドローン自体も需要がないし、やつている人もいないと推定され
アナログサーボ信号をシリアルのバイナリに変換する方が需要(一日で100カウント)が
あるがひまで多少理解できるので作ってみる
ふろ行ってくらーー2022/5/19 21:09
もう、めんどいので(完成)とする2022/5/20 0:59
検索ロボットと外人は、結構いそうな気かするが
ドローンやっている人で100カウントいくんか?
なんか100カウント行きそうなんだけど!!
完全になめぷ


引用元　株式会社センシンロボティクス


https://qiita.com/k-koh/items/b7d8d978a204f37b3fa1


https://github.com/mavlink/c_library_v2/blob/master/checksum.h



STM32G031のプログラム(完成)


```c++



//MAVLink_CRC_031_1


#include <Arduino.h>


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

void p_hex(unsigned char x){

  //ヘキサに値を設定
  // packet move
  char out_buff[8];
  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
  Serial.print(out_buff);

    
}//printf_hex


void crc_accumulate(unsigned char data, unsigned short *crcAccum)
{
    
    
    p_hex(data);
    
    
    unsigned char tmp;

    tmp = data ^ (unsigned char)(*crcAccum &0xff);
    tmp ^= (tmp<<4);
    *crcAccum = (*crcAccum>>8) ^ (tmp<<8) ^ (tmp <<3) ^ (tmp>>4);

}//crc_accumulate


unsigned short crc_calculate(unsigned char *pBuffer, int length)
{
    unsigned short crcTmp = 0xffff; //X25_INIT_CRC

    for(int ii=0;ii<length;ii++){
        crc_accumulate(pBuffer[ii] , &crcTmp);
    }
    return crcTmp;
}//crc_calculate


void crc_accumulate_buffer(unsigned short *crcAccum, char *pBuffer, int length)
{
  unsigned char *p = (unsigned char*)pBuffer;

  for(int ii=0;ii<length;ii++){
                crc_accumulate(p[ii], crcAccum);
        }
}//crc_accumulate_buffer


//初期化
void setup() {

  delay(3000); //not Delete

  Serial.begin(9600);

  Serial.print("<ST>\r\n");

} //setup


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

    unsigned char buff1[] = { 0x32,0x00,0x00,0xca,0x01,0x01,0x7a,0xe6,0x00 };
    
             char buff2[] = {                     0x0e,0x04,0x19,0x0f,0x0f,0x0f,
0x0f,0x0f,0x0f,0x0f,0x0f,0x0c,0x00,0x00,0x0f,0xff,0xff,0xff,0xff,0xff,0x0f,0xff,
0xff,0xff,0xff,0xff,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x0f,0x0f };
    
    
    Serial.print("START\r\n");
    
    
    unsigned short ret = crc_calculate(buff1, 9);
    
    Serial.print("\r\n");
    
    Serial.println(ret);

    
    unsigned short checksum = 43558;
    
    crc_accumulate_buffer(&checksum, buff2, 50);
    
    Serial.print("\r\n");
    
    Serial.println(checksum);
    
    /*
    unsigned short chk=0;
    for(int ii=0;ii<256;ii++){
        
        chk = 63626;
        crc_accumulate((unsigned char)ii,&chk);
        printf("%d\r\n",chk);
    
    }//for
    */
    
    
    unsigned short chk=0;
    chk = 63626;
    crc_accumulate((unsigned char)0xEF,&chk);
    Serial.println(chk);
 
    
    chk = 63626;
    crc_accumulate((unsigned char)0xD7,&chk);
    Serial.println(chk);
 

  //2秒の待ち
  delay(2000);    //debug

} //loop





```






名前は、まだない その1 43558なので(完成)とする


```

START
[32][00][00][CA][01][01][7A][E6][00]
43558


```



```c++

#include <stdio.h>



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

void p_hex(unsigned char x){

  //ヘキサに値を設定
  // packet move
  char out_buff[8];
  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
  printf(out_buff);

    
}//printf_hex


void crc_accumulate(unsigned char data, unsigned short *crcAccum)
{
    
    
    p_hex(data);
    
    
    unsigned char tmp;

    tmp = data ^ (unsigned char)(*crcAccum &0xff);
    tmp ^= (tmp<<4);
    *crcAccum = (*crcAccum>>8) ^ (tmp<<8) ^ (tmp <<3) ^ (tmp>>4);
    
    //*crcAccum = 0x1234;
}


unsigned short crc_calculate(unsigned char *pBuffer, unsigned short length)
{
    unsigned short crcTmp = 0xffff; //X25_INIT_CRC

    for(int ii=0;ii<length;ii++){
        crc_accumulate(pBuffer[ii] , &crcTmp);
    }
    return crcTmp;
}




int main(void){
    // Your code here!
    
    unsigned char buff1[] = { 0x32,0x00,0x00,0xca,0x01,0x01,0x7a,0xe6,0x00 };
    
    
    printf("START\r\n");
    
    
    unsigned short ret = crc_calculate(buff1, 9);
    
    printf("\r\n");
    
    printf("%d",ret);
    
    
    
}//main


```

名前は、まだない その2　63626になっているので(完成)


```


START
[32][00][00][CA][01][01][7A][E6][00]
43558
[0E][04][19][0F][0F][0F][0F][0F][0F][0F][0F][0C][00][00][0F][FF][FF][FF][FF][FF][0F][FF][FF][FF][FF][FF][0F][0F][0F][0F][0F][0F][0F][0F][FF][FF][FF][FF][FF][FF][FF][FF][FF][FF][00][00][00][00][0F][0F]
63626
[EF]13395
[D7]35224

```


```c++

#include <stdio.h>



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

void p_hex(unsigned char x){

  //ヘキサに値を設定
  // packet move
  char out_buff[8];
  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
  printf(out_buff);

    
}//printf_hex


void crc_accumulate(unsigned char data, unsigned short *crcAccum)
{
    
    
    p_hex(data);
    
    
    unsigned char tmp;

    tmp = data ^ (unsigned char)(*crcAccum &0xff);
    tmp ^= (tmp<<4);
    *crcAccum = (*crcAccum>>8) ^ (tmp<<8) ^ (tmp <<3) ^ (tmp>>4);

}//crc_accumulate


unsigned short crc_calculate(unsigned char *pBuffer, int length)
{
    unsigned short crcTmp = 0xffff; //X25_INIT_CRC

    for(int ii=0;ii<length;ii++){
        crc_accumulate(pBuffer[ii] , &crcTmp);
    }
    return crcTmp;
}//crc_calculate


void crc_accumulate_buffer(unsigned short *crcAccum, char *pBuffer, int length)
{
	unsigned char *p = (unsigned char*)pBuffer;

	for(int ii=0;ii<length;ii++){
                crc_accumulate(p[ii], crcAccum);
        }
}//crc_accumulate_buffer


int main(void){
    // Your code here!
    
    unsigned char buff1[] = { 0x32,0x00,0x00,0xca,0x01,0x01,0x7a,0xe6,0x00 };
    
             char buff2[] = {                     0x0e,0x04,0x19,0x0f,0x0f,0x0f,
0x0f,0x0f,0x0f,0x0f,0x0f,0x0c,0x00,0x00,0x0f,0xff,0xff,0xff,0xff,0xff,0x0f,0xff,
0xff,0xff,0xff,0xff,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x0f,0x0f };

    
    
    printf("START\r\n");
    
    
    unsigned short ret = crc_calculate(buff1, 9);
    
    printf("\r\n");
    
    printf("%d\r\n",ret);
    
    unsigned short checksum = 43558;
    
    crc_accumulate_buffer(&checksum, buff2, 50);
    
    printf("\r\n");
    
    printf("%d\r\n",checksum);
    
    /*
    unsigned short chk=0;
    for(int ii=0;ii<256;ii++){
        
        chk = 63626;
        crc_accumulate((unsigned char)ii,&chk);
        printf("%d\r\n",chk);
    
    }//for
    */
    
    
    unsigned short chk=0;
    chk = 63626;
    crc_accumulate((unsigned char)0xEF,&chk);
    printf("%d\r\n",chk);
 
    
    chk = 63626;
    crc_accumulate((unsigned char)0xD7,&chk);
     printf("%d\r\n",chk);
 
    
    
}//main


```