May I have extra eyes on my attempt to build a basic circular buffer?

I'm attempting to build my own FIFO circular buffer with integer arrays and I'm skeptical of the serial output because my prints do not look as if the data is moving FIFO. I've attached a screenshot of the serial output below.

My goal is to build four circular buffers that accept 1s and 0s based on sensor values. For the time being, the sensor values are simulated with a random number generator and only one circular buffer is active. Once sensor data is collected, I want to periodically calculate the summation of the buffer as data moves through it. If at any time the summation is greater than half the number of buffer indices, the system will run alarm conditionals. Otherwise, the system will continue to read sensor values and calculate summations.

I've tried to print one of the circular buffers when the buffer resets back to the tail. The print statements do not seem as if the data is shifting first in, first out. It looks more like large sets moving in/out of the buffer. Code pasted below.

Please let me know if there are further questions or concerns. I will gladly appreciate feedback on this. Thanks.

<

int circular_buffer0[10];
// additional circular buffers will be enabled later
int circular_buffer1[10];
int circular_buffer2[10];
int circular_buffer3[10];

int buff_index = 0;
int buff_head = (sizeof(circular_buffer0)/sizeof(circular_buffer0[0])) -1;

int buffer_sum = 0;
int max_sum = (sizeof(circular_buffer0)/sizeof(circular_buffer0[0]))/2;

long sensor_read;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("Initialize...");
  // if analog input pin 0 is unconnected, random analog
  // noise will cause the call to randomSeed() to generate
  // different seed numbers each time the sketch runs.
  // randomSeed() will then shuffle the random function.
  randomSeed(analogRead(0));
}

void loop() {
  // simulate reading sensor values 
  updateCircularBuffer(0, readSensor());
  delay(100);
}


bool readSensor()
{
  // simulates sensor values
  sensor_read = random(1, 11);
  // if sensor value is above 5, return true, else return false
  if (sensor_read > 5)
  {
    return true; 
  }
  else
  {
    return false;
  }
}

// accepts the current channel and bool value of sensor read
// in the future, this function will be looped by four channels
void updateCircularBuffer(int channel, bool isLowPower)
{
     if (buff_index > buff_head)
     {
        buff_index = 0;  // reset the index if value is greater than buffer head
     } 
     switch(channel)
     {
        case 0:
          circular_buffer0[buff_index] = isLowPower;
          break;
        case 1:
          circular_buffer1[buff_index] = isLowPower; 
          break;
        case 2:
          circular_buffer2[buff_index] = isLowPower; 
          break;
        case 3:
          circular_buffer3[buff_index] = isLowPower; 
          break;
        default:
          break;
     }

     if (checkCircularBuffer(channel))
     {
        // INSERT ALARM CONDITIONAL HERE
     }

     // print to watch the data move through array - FIFO
     if (buff_index == 0)
     {
        Serial.print("["); Serial.print(circular_buffer0[0]); Serial.print("], ");
        Serial.print("["); Serial.print(circular_buffer0[1]); Serial.print("], ");
        Serial.print("["); Serial.print(circular_buffer0[2]); Serial.print("], ");
        Serial.print("["); Serial.print(circular_buffer0[3]); Serial.print("], ");
        Serial.print("["); Serial.print(circular_buffer0[4]); Serial.print("], ");
        Serial.print("["); Serial.print(circular_buffer0[5]); Serial.print("], ");
        Serial.print("["); Serial.print(circular_buffer0[6]); Serial.print("], ");
        Serial.print("["); Serial.print(circular_buffer0[7]); Serial.print("], ");
        Serial.print("["); Serial.print(circular_buffer0[8]); Serial.print("], ");
        Serial.print("["); Serial.print(circular_buffer0[9]); Serial.println("]");
     }

     // increment buffer index
     buff_index++;
}

// returns bool based on sum of circular buffer
bool checkCircularBuffer(int channel)
{
      buffer_sum = 0;

      for (int i = 0; i < buff_head; i++)
      {  
        buffer_sum += circular_buffer0[i];
      }

      if (buffer_sum > max_sum)
      {
        return true;
      }
      else 
      {
        return false;
      }
}

/>

Seems you don’t really need a true circular buffer as your test does not care about order of arrival of the data. You just need to reset the index at the start when you overflow

You print random data every 10 steps so you can’t see anything the whole array has changed every time => Print at every step but In a circular buffer you need to move where you are in the buffer, you can’t print from 0 to 9 always to visually see the circular buffer thingy happening

Say you have just written at index 4 the history buffer to print is 4 3 2 1 0 9 8 7 6 5
Then you write in position 5 and the history buffer to print is 5 4 3 2 1 0 9 8 7 6
Then you write in position 6 and the history buffer to print is 6 5 4 3 2 1 0 9 8 7

Weird variable name for buf_head when it’s the index of the tail of the array

Careful as well, You will need 4 different index variables to deal with your 4 arrays

You can simplify your readSensor() function to just be

 bool readSensor()
{
  return random(1, 11) > 5;   // simulates sensor values
}

Using int is super expensive in memory to just store 0 and 1. ideally use bits and bitwise operations or At the very least go to 1 byte type (char, bool, uint8_t) and since your sensor function returns a bool, bool would make sense.

as J-M-L said and based on your code, no need for a circular buffer because the code makes a decision only after the buffer is full

#define MaxCnt  100
#define MaxSum  (MaxCnt / 2)

unsigned int cnt = 0;
unsigned int sum = 0;

char s [80];

void setup() {
    Serial.begin(9600);

    randomSeed(analogRead(0));
    cnt = 0;
}

// report sum of readings >= total # of readings
void loop() {
    sum += (5 < random(1, 11) ? 1 : 0);

    if (MaxCnt <= cnt++)  {
        sprintf (s, " MaxSum %6d, sum %6d - %s",
            MaxSum, sum, (char*)(MaxSum <= sum ? "exceed" : "lower"));
        Serial.println (s);

        sum = 0;
        cnt = 0;
    }
}

however, i can see the value of a circular buffer if you need to constantly check for a threshold after each sensor reading. is that what you intend to do?

i can see the value of a circular buffer if you need to constantly check for a threshold after each sensor reading.

results from code below

idxByte, oldBit, newBit, sum, buffer (bits from msb to lsb)

⸮00 00 00 00
      0: 0  0    0   -  00 00 00 00
      0: 0  0    0   -  00 00 00 00
      0: 0  1    1   -  20 00 00 00
      0: 0  0    1   -  20 00 00 00
      0: 0  1    2   -  28 00 00 00
      0: 0  0    2   -  28 00 00 00
      0: 0  0    2   -  28 00 00 00
      0: 0  1    3   -  29 00 00 00
      1: 0  1    4   -  29 80 00 00
      1: 0  0    4   -  29 80 00 00
      1: 0  1    5   -  29 a0 00 00
      1: 0  1    6   -  29 b0 00 00
      1: 0  0    6   -  29 b0 00 00
      1: 0  0    6   -  29 b0 00 00
      1: 0  0    6   -  29 b0 00 00
      1: 0  1    7   -  29 b1 00 00
      2: 0  0    7   -  29 b1 00 00
      2: 0  1    8   -  29 b1 40 00
      2: 0  1    9   -  29 b1 60 00
      2: 0  0    9   -  29 b1 60 00
      2: 0  1   10   -  29 b1 68 00
      2: 0  1   11   -  29 b1 6c 00
      2: 0  1   12   -  29 b1 6e 00
      2: 0  0   12   -  29 b1 6e 00
      3: 0  0   12   -  29 b1 6e 00
      3: 0  0   12   -  29 b1 6e 00
      3: 0  0   12   -  29 b1 6e 00
      3: 0  1   13   -  29 b1 6e 10
      3: 0  0   13   -  29 b1 6e 10
      3: 0  1   14   -  29 b1 6e 14
      3: 0  0   14   -  29 b1 6e 14
      3: 0  1   15   -  29 b1 6e 15
      0: 0  1   16 * -  a9 b1 6e 15
      0: 0  0   16 * -  a9 b1 6e 15
      0: 1  0   15   -  89 b1 6e 15
      0: 0  0   15   -  89 b1 6e 15
      0: 1  0   14   -  81 b1 6e 15
      0: 0  1   15   -  85 b1 6e 15
      0: 0  1   16 * -  87 b1 6e 15
      0: 1  0   15   -  86 b1 6e 15
      1: 1  0   14   -  86 31 6e 15
      1: 0  1   15   -  86 71 6e 15
      1: 1  0   14   -  86 51 6e 15
      1: 1  0   13   -  86 41 6e 15
      1: 0  0   13   -  86 41 6e 15
      1: 0  1   14   -  86 45 6e 15
      1: 0  1   15   -  86 47 6e 15
      1: 1  0   14   -  86 46 6e 15
      2: 0  0   14   -  86 46 6e 15
      2: 1  0   13   -  86 46 2e 15
      2: 1  0   12   -  86 46 0e 15
      2: 0  1   13   -  86 46 1e 15
      2: 1  0   12   -  86 46 16 15
      2: 1  0   11   -  86 46 12 15
      2: 1  1   11   -  86 46 12 15
      2: 0  1   12   -  86 46 13 15
      3: 0  1   13   -  86 46 13 95
      3: 0  0   13   -  86 46 13 95
      3: 0  0   13   -  86 46 13 95
      3: 1  0   12   -  86 46 13 85
      3: 0  0   12   -  86 46 13 85
      3: 1  1   12   -  86 46 13 85
      3: 0  0   12   -  86 46 13 85
      3: 1  1   12   -  86 46 13 85
      0: 1  1   12   -  86 46 13 85
      0: 0  1   13   -  c6 46 13 85
      0: 0  1   14   -  e6 46 13 85
      0: 0  1   15   -  f6 46 13 85
      0: 0  0   15   -  f6 46 13 85
      0: 1  1   15   -  f6 46 13 85
      0: 1  0   14   -  f4 46 13 85
      0: 0  0   14   -  f4 46 13 85
      1: 0  1   15   -  f4 c6 13 85
      1: 1  1   15   -  f4 c6 13 85
      1: 0  0   15   -  f4 c6 13 85
      1: 0  0   15   -  f4 c6 13 85
      1: 0  1   16 * -  f4 ce 13 85
      1: 1  0   15   -  f4 ca 13 85
      1: 1  0   14   -  f4 c8 13 85
      1: 0  0   14   -  f4 c8 13 85
      2: 0  1   15   -  f4 c8 93 85
      2: 0  1   16 * -  f4 c8 d3 85
      2: 0  0   16 * -  f4 c8 d3 85
      2: 1  1   16 * -  f4 c8 d3 85
      2: 0  0   16 * -  f4 c8 d3 85
      2: 0  1   17 * -  f4 c8 d7 85
      2: 1  1   17 * -  f4 c8 d7 85
      2: 1  1   17 * -  f4 c8 d7 85
      3: 1  1   17 * -  f4 c8 d7 85
      3: 0  0   17 * -  f4 c8 d7 85
      3: 0  0   17 * -  f4 c8 d7 85
      3: 0  0   17 * -  f4 c8 d7 85
      3: 0  1   18 * -  f4 c8 d7 8d
      3: 1  1   18 * -  f4 c8 d7 8d
      3: 0  0   18 * -  f4 c8 d7 8d
      3: 1  0   17 * -  f4 c8 d7 8c
#define Nbyte   4
#define MaxCnt  (8*Nbyte)
#define MaxSum  (MaxCnt / 2)

byte buf [Nbyte] = {};
int  idxByte = 0;
int  idxBit  = 0;

unsigned int cnt = 0;
unsigned int sum = 0;

char s [80];

// -------------------------------------
void
dispBuf (
    byte *p,
    int   nByte )
{
    while (nByte--)  {
        sprintf (s, " %02x", *p++);
        Serial.print (s);
    }
    Serial.println ("");
}

// -------------------------------------
void setup() {
    Serial.begin(9600);

    randomSeed(analogRead(0));

    dispBuf (& buf [0], Nbyte);
}

// -------------------------------------
// report sum of readings >= total # of readings
void bufUpdate (
    byte *buf,
    int  &idxByte,
    int  &idxBit )
{
    byte bit;

    // remove old bit
    bit            = (buf [idxByte] & (1 << (7 - idxBit)) ? 1 : 0);
    sum           -= bit;
    buf [idxByte] &= ~(1 << (7 - idxBit));

    sprintf (s, " %6d: %d ", idxByte, bit);
    Serial.print (s);

    // add new bit
    bit            = (5 < random(1, 11) ? 1 : 0);
    sum           += bit;
    buf [idxByte] |= bit << (7 - idxBit);

    if (8 <= ++idxBit)  {
        idxBit = 0;
        if (Nbyte <= ++idxByte)
            idxByte = 0;
    }

    sprintf (s, " %d %4d %s - ", bit, sum, MaxSum <= sum ? "*" : " ");
    Serial.print (s);

    dispBuf (buf, Nbyte);
}

// -------------------------------------
void loop() {
    bufUpdate (buf, idxByte, idxBit);
}