似非Arduinoサークルバッファその2
前回、”++i%N”を使った似非サークルバッファを作りました。固定長変数ですと前回のスケッチでOKですが、BluetoothのMIDIなどでは固定長の変数が入ってくるとは限りません。またfor文で配列を回し循環するときは++i%Nよりi++; if(i>=N)i=i-N;に分けた方が早い事があるようで今回は修正しています。
固定長ではない変数が入ってきた時、サークルバッファでは最初のアドレスと終わりのアドレスを記憶しサークルバッファのアドレスを0に連結させるのが一般的なようです。
今回は2次元配列にアドレスを記憶,サークルバッファに変数を保存、アドレスの変化を検知し処理をします。可変長の変数でもサークルバッファの0への連結部分を処理してみました。
※ランダム可変長の変数を作るのが手間ですし今回はサークルバッファの説明なのでmovingValの変数にしました。実際は”if(0<可変長変数.length){”で変数の長さを取得、処理してください
可変長似非サークルバッファ
int cBindex[128][2];/*サークルバッファのインデックス*/
uint8_t movingVal = 10; /*可変長の変数のつもり0-127*/
void setup() {
Serial.begin(115200);
Serial.println("CircleBuffer Test2");
randomSeed(analogRead(0));
for (uint8_t i = 0; i < 128; i++) {
for (uint8_t j = 0; j < 2; j++) {
cBindex[i][j]=999;/*0-255はつかうので999*/
}
}
}
byte randNumber[128];
uint8_t randNCnt=0;
uint8_t cBuff1[256];
uint8_t cBCnt=0;
uint8_t cBindexCntStart=0;
void loop() {
/*****0-127乱数発生 配列に格納*****/
randNumber[randNCnt++] = random(0, 127);
/*実際はif(0<可変長変数.length){*/
if (movingVal < randNCnt){
cBindex[cBindexCntStart][1]= cBCnt+movingVal;
cBindex[cBindexCntStart][0]= cBCnt;
for (uint8_t i = 0; i < randNCnt; i++) {
cBuff1[cBCnt] = randNumber[i];
Serial.print(cBuff1[cBCnt],HEX);
Serial.print(":");
//cBCnt= ++cBCnt%256;
cBCnt++;
if(cBCnt>=256)cBCnt=cBCnt-256;
}
randNCnt = 0;
Serial.print(" start:");
Serial.print(cBindex[cBindexCntStart][0]);
Serial.print(" end :");
Serial.println(cBindex[cBindexCntStart][1]%256);
cBindexCntStart=++cBindexCntStart%128;
}
/*2次元配列の変化を検知しアドレスを取得*/
int SearchCnt ;
int Hit = 0;
int Hitend = 0;
SearchCnt = cBindexCntStart+100;
SearchCnt = SearchCnt%128;
for (uint8_t i = 0; i < 128; i++) {
SearchCnt = SearchCnt + i;
if(SearchCnt>=128)SearchCnt=SearchCnt-128;
if(cBindex[SearchCnt][0] != 999) {
Hit = cBindex[SearchCnt][0];
cBindex[SearchCnt][0]= 999;
Hitend = cBindex[SearchCnt][1];
Hitend = Hitend % 256;
cBindex[SearchCnt][1]= 999;
break;
}
}
/*サークルバッファより値を取り出す。"++i%N"で0の連結*/
if(Hit != Hitend){
uint8_t preHit = Hit;
for(;;){
Serial.print(cBuff1[Hit] ,HEX);
if(Hit == Hitend)break;
Hit = ++Hit%256;
Serial.print(":");
}
Serial.print(": HitSt:");
Serial.print(preHit);
Serial.print(" HitEnd:");
Serial.println(Hitend);
Serial.println("-----------------------------");
delay(300);
}
}
前回と今回のスケッチを比べると前回は0への連結を4の倍数にしIndexのスタートを記憶、252⇒0と自動的に循環させています。今回は可変長ですので255の次が0になるように書いていますがその分Indexの終わりとスタートで配列の必要数が2倍に増えます。その点を考慮すれば固定長でも使えますので今回のスケッチの方が良いかと思われます。
※上記コードは付属のパーツは必要ありません。またArduinoでもESP32でも動きます。