ここ数回ビット列の生成、復元などコチョコチョしたことをやっており。その中でCRC(Cyclic Redundancy Check、巡回冗長検査)の計算をせにゃならんことがあり。CRC計算といえば多項式の割り算デス。そういえばScilabは多項式の計算出来たな~そいつを使ってなんとからなんのか?ダメか?
※「手習ひデジタル信号処理」投稿順 Indexはこちら
※Windows11上で、Scilab6.1.1およびScilab上のツールボックス Scilab Communication Toolbox 0.3.1(以下comm_tbx)を使用させていただいとります。
Scilabは多項式の定義が可能です。伝達関数の定義などで使うアレです。当然、多項式の割り算関数もあります。最初、なんとかならぬか、と考えました。しかし、
Scilabは10進数の世界、基本、倍精度浮動小数
なんであります。多項式が定義できるといっても係数は倍精度浮動浮動小数(もっといえばそれを使った複素数)範囲です。一方CRC計算は「2を法」とする世界で0か1。う~む、なんとかそこを乗り越える方法がないものか?数学苦手の年寄には難易度高すぎましたです。そこで過去回でPythonで実装済のコードを流用することに。なんだかな~。カッコ悪いな~。
過去回でのCRC8計算
MicroPython(Pythonでも同じ関数で計算可能)でCRC8計算を実装して使ってみたのは以下の別シリーズ回です。タイトル通りAHT21B温湿度センサの通信データの末尾に載ってくるCRC値を検査するためでした。
部品屋根性(77) AHT21B、CRC8でのデータ検査を追加。ラズパイPython
今回は上記で使用したPythonコードを「素直に」Scliabに移植してみます。ぜんぜんScilabっぽくないけれども。
また以下の別シリーズ回では、MicroChip社製PIC16Fマイコンの内蔵ペリフェラルがハードウエアCRC計算に対応していたので使用してみています。
PIC三昧(18) CRC、データ配列のCRC8をハードで計算、PIC16F18855
そのとき検算につかった値を今回も検算に使用してみたいと思います。
PythonコードをScilabへ移植
淡々とPythonからScilabへ移植したCRC8関数が以下に。全然Scilabっぽくないけれども、Pythonとは1対1対応です。第1引数に計算対象のリスト(8ビット整数範囲の数値リスト)、第2引数に特性多項式(多項式の係数を整数表記したもの)、第3引数に初期値(8ビット整数)を与えます。
// calculate CRC8 (by J.Halfmoon Nov. 23, 2023) // blis: byte data list // ply: CRC characteristic polynomial // opt: initial Value function crc=calcCRC8(blis, ply, opt) crc = opt; for item = blis do crc = bitxor(crc, item); for idx = 1:8 do if bitand(crc, 128)<>0 then crc = bitxor(ply, bitand(255, crc*2)); else crc = bitand(255, crc*2) end end end endfunction
動作結果
黄色のマーカ部分が特性多項式と初期値部分です。上の例がPoly=0x31(十進で49)、init=0xFF(十進で255)のAHT21Bセンサ用です。Poly=0x31は「Maxim社方式のCRC8」と同じですが、初期値が0ではなく0xFFです。下の例がデジタルテレビなどで使われるDVB S2方式のCRC8です。PIC16FのハードウエアCRC計算機は各種方式対応していますが、たまたま初期値がこれだったというだけのものです。
Scilabにも16進10進変換関数があるのですが、それを使うと記述が長くなるので、全部10進です。やっぱりScilabは10進の世界よな。。。