/*

  Author: GC1CEO
  Date: 10/27/2024

  A testbed for working with bitwise operations and bit/byte
  Arduino functions.

*/



byte leds = 0b00000000;  // byte of 8 leds, turned off by default

void setup() {
  // Setting up pin modes for LEDs (Assuming pins 2 to 9 are LEDs)
  for (int i = 2; i <= 9; i++) {
    pinMode(i, OUTPUT);
  }
  Serial.begin(115200);
}

void loop() {
  /*

    // Turn on LED 1 (set bit 0 to 1)
    leds = leds | 0b00000001;  // OR operation turns on the first LED
    updateLeds(leds);
    delay(1000);

    // Turn off LED 1 (set bit 0 to 0)
    leds = leds & 0b11111110;  // AND operation clears the first LED
    updateLeds(leds);
    delay(1000);

  */

  altAll(leds);

}

void updateLeds(byte ledState) {
  /*
    This function updates each of the 8 LED pins
    to whats in leds / ledState to allow for
    direct bitwise manipulation.

  */
  for (int i = 0; i < 8; i++) {
    digitalWrite(i + 2, (ledState >> i) & 0x01);  // Write each bit to the corresponding LED
  }
}

void cycleLeds(byte ledState) {
  /*
    This function cycles through each LED pin
    and sets the bit (to 1), turns on that LED
    pin, delays 1 sec, clears the bit (to 0),
    and then turns it off.

  */
  for (int i = 0; i < 8; i++) {
    bitSet(ledState, i);
    digitalWrite(i + 2, (ledState >> i) & 0x01);
    readLeds(ledState);
    delay(1000);
    bitClear(ledState, i);
    digitalWrite(i + 2, (ledState >> i) & 0x01);
  }
}

void allOn(byte ledState) {
  for (int i = 0; i < 8; i++) {
    bitWrite(ledState, i, 1);
    digitalWrite(i + 2, (ledState >> i) & 0x01);
  }


}

void allOff(byte ledState) {
  for (int i = 0; i < 8; i++) {
    bitWrite(ledState, i, 0);
    digitalWrite(i + 2, (ledState >> i) & 0x01);
  }
}

void blinkAll(byte ledState, int delayVal) {
  allOff(ledState);
  delay(delayVal);
  allOn(ledState);
  delay(delayVal);
}

void cycleLeds_r(byte ledState) {
  for (int i = 7; i >= 0; i--) {
    bitSet(ledState, i);
    digitalWrite(i + 2, (ledState >> i) & 0x01);
    readLeds(ledState);
    delay(1000);
    bitClear(ledState, i);
    digitalWrite(i + 2, (ledState >> i) & 0x01);
  }


}

void blinkLed(byte ledState, int ledNum) {
  bitSet(ledState, ledNum);
  digitalWrite(ledNum + 2, (ledState >> ledNum) & 0x01);
  delay(1000);
  bitClear(ledState, ledNum);
  digitalWrite(ledNum + 2, (ledState >> ledNum) & 0x01);

}

void readLeds(byte ledState) {
  Serial.print("Bits: ");
  for (int i = 7; i >= 0; i--) {
    Serial.print(bitRead(ledState, i));

  }
  Serial.println();
}

void readLeds_r(byte ledState) {
  Serial.print("Bits: ");
  for (int i = 0; i <= 7; i++) {
    Serial.print(bitRead(ledState, i));

  }
  Serial.println();
}

void altAll(byte ledState) {
  allOff(ledState);
  for (int i = 0; i <= 7; i++) {
    if (i % 2 == 0) {
      bitSet(ledState, i);
      digitalWrite(i + 2, (ledState >> i) & 0x01);
    } else {
      bitClear(ledState, i);
      digitalWrite(i + 2, (ledState >> i) & 0x01);
    }
  }
  delay(1000);
  for (int i = 0; i <= 7; i++) {
    if (i % 2 != 0) {
      bitSet(ledState, i);
      digitalWrite(i + 2, (ledState >> i) & 0x01);
    } else {
      bitClear(ledState, i);
      digitalWrite(i + 2, (ledState >> i) & 0x01);
    }
  }
  delay(1000);
}