Compiler Error asking me to #define something that is ALREADY #defined

I am getting a compiler error that seems to make zero sense when I research a solution.

Preface: my coding back ground is less than a pre-schooler level. I use Chat GPT to help quite a bit, I copy and paste a lot from git hub and tweak or modify to work. I am more like Mad Scientist behind frankenstein taking a little bit here and there to put together a monster. that I am sure has so many fundemental flaws but I digress.

Hardware spec
Arduino Giga R1 Wifi
3.3v sensors
MPS EVCS180x-S-Y-00A Eval boards to read current
Grove AC voltage sensor for AC voltage readings MCP6002
1602 LCDs with I2C backpacks using all 8 hex address on the 1 I2c line
Just bought this Sparkfun TCA964A Multiplexer so I can use the 9th LCD with the same hex 0x27 on the same I2C lines
10k potentiometers
Latching Buttons with 10k pull down resistors
(4) 16channel Relay boards by sainsmart with low/on high/off 5v pin outs (using 3.3to5v level shifters from my IO pins)
Separate 12vdc power supply
separate 5vdc power supply

At this point I have successfully pieced together code to:

  1. get the Light bulbs to operate off the potentiometer values,
  2. Get the 4 buttons to control 4 outlet relays
  3. Get the analog pin A6 to convert digital signal from the Grove AC sensor into a value that I print on LCD 6
  4. Setup I2C comms for 8 of the 9 LCD displays
  5. initialized the static text that will not change on the LCD displays

I am attempting to get a current sensor reading from my MPS1802 sensor using the Eval boards with a 44mv/amp sensitivity

The error is telling me "Compilation error: call to 'PureAnalogPin::operator int' declared with attribute error: Change me to a #define

The problem is that I have changed it to #define and I get the same error, I have tried changing back and forth between const int and a float and #define, all of which tell me to change to #define.

before this compiler error, I have spent the last 2 days trying to run different code iterations to get current, I used an I2C ADS1115 16-bit ADC to try and get more precise but that not only never worked with 15 different code iterations, it ended up causing my LCDs to read whacky characters through what I am guessing was interference on the SDA and SCL lines, I thought that might be due to lack of pull up resistors on the SCL and SDA lines so I added those to no avail. and gave up and pulled that ADC back out of the unit altogether. Also note, Being that we are sensing AC current my code cant just read voltage changes on the output pin of the current sensor like you would if you ran DC crossed the MC1802 sensor, so this code is designed to get the RMS current, when I test it by itself it seems to be about 20% off, but haven't tweaked it yet.

right now the hurdle is that #define requirement that is not making sense, so I can move on to tweaking and display wattages on specific LCDS

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Define constants for voltage reference and ADC resolution
#define VOLTAGE_REFERENCE 3.3    // Arduino operating at 3.3V
#define ADC_RESOLUTION 1023      // Resolution of Arduino ADC for 3.3V
#define ZERO_CURRENT_VOLTAGE (VOLTAGE_REFERENCE / 2) // 1.65V for zero current
#define SENSITIVITY 0.044        // Sensitivity in V/A
#define NUM_SAMPLES 100          // Number of samples to average for RMS calculation

// Pin definitions using #define for readability
#define CURRENT_SENSOR_PIN_A A9
#define CURRENT_SENSOR_PIN_B A10
#define CURRENT_SENSOR_PIN_C A11
#define CURRENT_SENSOR_PIN_D A12
#define INVERTER_AC_SENSE A6

// Global variable to store the inverter voltage
double INVERTER_VAC = 0;

// Global variables to store current and wattage for each channel
float currentA, currentB, currentC, currentD;
double wattageA, wattageB, wattageC, wattageD;

// Create an array of LiquidCrystal_I2C objects for each address
LiquidCrystal_I2C lcds[] = {
  LiquidCrystal_I2C(0x20, 16, 2),  // CHANNEL A TOTALS
  LiquidCrystal_I2C(0x21, 16, 2),  // PV WATT/INV AC OUT
  LiquidCrystal_I2C(0x22, 16, 2),  // PV WATTS
  LiquidCrystal_I2C(0x23, 16, 2),  // CHANNEL B TOTALS
  LiquidCrystal_I2C(0x24, 16, 2),  // CHANNEL C TOTALS
  LiquidCrystal_I2C(0x25, 16, 2),  // CHANNEL D TOTALS
  LiquidCrystal_I2C(0x26, 16, 2),  // INVERTER W
  LiquidCrystal_I2C(0x27, 16, 2)   // AC-IN WATTS
};
const int numLcds = sizeof(lcds) / sizeof(lcds[0]); // Number of LCDs

// Pin declarations for buttons, receptacles, potentiometers, and light channels
#define buttonPin1A 9  // TURNS ON RECEPTACLES CHANNEL A
#define buttonPin1B 8  // TURNS ON RECEPTACLES CHANNEL B
#define buttonPin1C 7  // TURNS ON RECEPTACLES CHANNEL C
#define buttonPin1D 6  // TURNS ON RECEPTACLES CHANNEL D
#define receptaclesChannel_B 43  // RELAY THAT ACTIVATES THE OUTLETS CHANNEL B
#define receptaclesChannel_C 5  // RELAY THAT ACTIVATES THE OUTLETS CHANNEL C
#define receptaclesChannel_D 19  // RELAY THAT ACTIVATES THE OUTLETS CHANNEL D
#define receptaclesChannel_A 32  // RELAY THAT ACTIVATES THE OUTLETS CHANNEL A
#define potPinA A0  // CHANNEL A 10K POTENTIOMETER CONTROLS CHANNEL A LIGHTBULBS PINS 22-31
#define startLightA 22
#define endLightA 31
#define potPinB A1  // CHANNEL B 10K POTENTIOMETER CONTROLS CHANNEL B LIGHTBULBS PINS 33-42
#define startLightB 33
#define endLightB 42
#define potPinC A2  // CHANNEL C 10K POTENTIOMETER CONTROLS CHANNEL C LIGHTBULBS PINS 44-53
#define startLightC 44
#define endLightC 53
#define potPinD A3  // CHANNEL D 10K POTENTIOMETER CONTROLS CHANNEL D LIGHTBULBS PINS 4, 3, 2, 1, 0, 14, 15, 16, 17, 18
const int channelDPins[] = {4, 3, 2, 1, 0, 14, 15, 16, 17, 18};

// Function prototypes
float readACCurrent(int pin);
void readSensorAndDisplay();
double calculateWattage(double current, double voltage);
void controlReceptacles();
void controlLights();
void updateLights(int potPin, int startLight, int endLight);
void updateChannelDLights();

void setup() {
  Wire.begin();  // Start I2C communication on Pins 20 and 21
  Serial.begin(9600);

  // Initialize each LCD
  for (int i = 0; i < numLcds; i++) {
    lcds[i].begin();
    lcds[i].backlight();
    lcds[i].clear();

    // Prepare initial text for each LCD and update
    String line1, line2;
    switch (i) {
      case 0:
        line1 = "CHANNEL A TOTALS";
        line2 = "WATTS";
        break;
      case 1:
        line1 = "PV WATT/INV AC OUT";
        line2 = "EFFICIENCY %";
        break;
      case 2:
        line1 = "PV WATTS";
        line2 = "VDC       A";
        break;
      case 3:
        line1 = "CHANNEL B TOTALS";
        line2 = "WATTS";
        break;
      case 4:
        line1 = "CHANNEL C TOTALS";
        line2 = "WATTS";
        break;
      case 5:
        line1 = "CHANNEL D TOTALS";
        line2 = "WATTS";
        break;
      case 6:
        line1 = "INVERTER W";
        line2 = "VAC       A";
        break;
      case 7:
        line1 = "AC-IN WATTS";
        line2 = "VAC       A";
        break;
    }
    lcds[i].setCursor(0, 0);
    lcds[i].print(line1);
    lcds[i].setCursor(0, 1);
    lcds[i].print(line2);
  }

  // Set button pins as input
  pinMode(buttonPin1A, INPUT);
  pinMode(buttonPin1B, INPUT);
  pinMode(buttonPin1C, INPUT);
  pinMode(buttonPin1D, INPUT);

  // Set receptacle pins as output
  pinMode(receptaclesChannel_B, OUTPUT);
  pinMode(receptaclesChannel_C, OUTPUT);
  pinMode(receptaclesChannel_D, OUTPUT);
  pinMode(receptaclesChannel_A, OUTPUT);

  // Initially turn off the receptacles
  digitalWrite(receptaclesChannel_B, HIGH);
  digitalWrite(receptaclesChannel_C, HIGH);
  digitalWrite(receptaclesChannel_D, HIGH);
  digitalWrite(receptaclesChannel_A, HIGH);

  // Set light pins for all channels as output and turn them off
  for (int pin = startLightA; pin <= endLightA; ++pin) {
    pinMode(pin, OUTPUT);
    digitalWrite(pin, HIGH);
  }
  for (int pin = startLightB; pin <= endLightB; ++pin) {
    pinMode(pin, OUTPUT);
    digitalWrite(pin, HIGH);
  }
  for (int pin = startLightC; pin <= endLightC; ++pin) {
    pinMode(pin, OUTPUT);
    digitalWrite(pin, HIGH);
  }
  for (int i = 0; i < sizeof(channelDPins) / sizeof(channelDPins[0]); ++i) {
    pinMode(channelDPins[i], OUTPUT);
    digitalWrite(channelDPins[i], HIGH);
  }
}

void loop() {
  // Read the inverter AC voltage
  readSensorAndDisplay();

  // Read currents for each channel using temporary variables
  int pinA = CURRENT_SENSOR_PIN_A;
  int pinB = CURRENT_SENSOR_PIN_B;
  int pinC = CURRENT_SENSOR_PIN_C;
  int pinD = CURRENT_SENSOR_PIN_D;

  currentA = readACCurrent(pinA);
  currentB = readACCurrent(pinB);
  currentC = readACCurrent(pinC);
  currentD = readACCurrent(pinD);

  // Calculate wattages for each channel
  wattageA = calculateWattage(currentA, INVERTER_VAC);
  wattageB = calculateWattage(currentB, INVERTER_VAC);
  wattageC = calculateWattage(currentC, INVERTER_VAC);
  wattageD = calculateWattage(currentD, INVERTER_VAC);

  // Other control functions
  controlReceptacles();
  controlLights();

  delay(1000);  // Delay for 1 second before next read
}

/**
 * Reads the AC current from the specified pin.
 *
 * @param pin The analog pin to read the current from.
 * @return The RMS current in Amperes.
 */
float readACCurrent(int pin) {
  float sum = 0;
  for (int i = 0; i < NUM_SAMPLES; i++) {
    int sensorValue = analogRead(pin);  // Read the sensor value
    float voltage = sensorValue * (VOLTAGE_REFERENCE / ADC_RESOLUTION);  // Convert to voltage
    float current = (voltage - ZERO_CURRENT_VOLTAGE) / SENSITIVITY;      // Convert voltage to current
    sum += current * current;  // Sum the squares of currents
    delay(1);  // Delay for 1 millisecond between samples
  }
  float meanSquare = sum / NUM_SAMPLES;  // Calculate the mean square of current
  return sqrt(meanSquare);  // Return the RMS current (square root of mean square)
}

/**
 * Calculates the wattage from the current and voltage.
 *
 * @param current The current in Amperes.
 * @param voltage The voltage in Volts.
 * @return The wattage in Watts.
 */
double calculateWattage(double current, double voltage) {
  return current * voltage;
}

/**
 * Reads the sensor value from INVERTER_AC_SENSE and updates the global variable INVERTER_VAC.
 * Displays the average RMS voltage on the LCD.
 */
void readSensorAndDisplay() {
  static int index = 0;  // Current index in the circular buffer
  static double recentValues[10];  // Circular buffer to store recent RMS values
  static double sum = 0;  // Running sum of values in the buffer
  static int count = 0;  // Count of values in the buffer
  const int windowSize = 10;  // Number of values to average

  int sensorValue = 0;
  int maxV = 0;
  double VmaxD = 0;
  double Veff = 0;
  double avgVeff = 0;
  const double originalScaleFactor = 34.0;
  const double observedRMS = 77.0;
  const double expectedRMS = 120.0;

  // Calculate new scale factor
  double newScaleFactor = originalScaleFactor * (expectedRMS / observedRMS);

  // Read sensor values and store the maximum
  for (int i = 0; i < 100; i++) {
    sensorValue = analogRead(INVERTER_AC_SENSE);
    if (sensorValue > maxV) {
      maxV = sensorValue;
    }
    delay(1);
  }

  // Calculate RMS voltage
  VmaxD = (maxV * 5.0 / 1023.0) * newScaleFactor;
  Veff = VmaxD / sqrt(2);

  // Update the circular buffer and adjust the running sum
  sum -= recentValues[index];  // Subtract the old value from the sum (it's zero if not yet filled)
  recentValues[index] = Veff;  // Insert new RMS value
  sum += Veff;  // Add the new value to the sum

  index = (index + 1) % windowSize;  // Move to the next index, wrap around using modulo

  if (count < windowSize) {
    count++;  // Increase count until the buffer is filled
  }

  // Calculate the average of the values in the buffer
  if (count == windowSize) {
    avgVeff = sum / windowSize;  // Only calculate average if the buffer is full
  } else {
    avgVeff = sum / count;  // Calculate using the count if buffer not yet full
  }

  // Update global variable for INVERTER_VAC
  INVERTER_VAC = avgVeff;

  // Display the average RMS voltage on LCD
  lcds[6].setCursor(3, 1); // Set cursor for display (column 3, line 1)
  lcds[6].print(INVERTER_VAC);
}

/**
 * Controls the state of the receptacles based on button inputs.
 */
void controlReceptacles() {
  int buttonState1A = digitalRead(buttonPin1A);
  digitalWrite(receptaclesChannel_A, buttonState1A ? LOW : HIGH);
  int buttonState1B = digitalRead(buttonPin1B);
  digitalWrite(receptaclesChannel_B, buttonState1B ? LOW : HIGH);
  int buttonState1C = digitalRead(buttonPin1C);
  digitalWrite(receptaclesChannel_C, buttonState1C ? LOW : HIGH);
  int buttonState1D = digitalRead(buttonPin1D);
  digitalWrite(receptaclesChannel_D, buttonState1D ? LOW : HIGH);
}

/**
 * Controls the lights based on potentiometer inputs.
 */
void controlLights() {
  updateLights(potPinA, startLightA, endLightA);
  updateLights(potPinB, startLightB, endLightB);
  updateLights(potPinC, startLightC, endLightC);
  updateChannelDLights();
}

/**
 * Updates the state of the lights in the specified range based on the potentiometer input.
 *
 * @param potPin The analog pin connected to the potentiometer.
 * @param startLight The starting pin of the light range.
 * @param endLight The ending pin of the light range.
 */
void updateLights(int potPin, int startLight, int endLight) {
  int potValue = analogRead(potPin);  // Read the potentiometer value
  int numLights = map(potValue, 0, 1023, 0, endLight - startLight + 1);  // Map the value to the number of lights
  for (int pin = startLight; pin < startLight + numLights; ++pin) {
    digitalWrite(pin, LOW);  // Turn on the lights
  }
  for (int pin = startLight + numLights; pin <= endLight; ++pin) {
    digitalWrite(pin, HIGH);  // Turn off the remaining lights
  }
}

/**
 * Updates the state of the lights in channel D based on the potentiometer input.
 */
void updateChannelDLights() {
  int potValueD = analogRead(potPinD);  // Read the potentiometer value
  int numLightsD = map(potValueD, 0, 1023, 0, sizeof(channelDPins) / sizeof(channelDPins[0]));  // Map the value to the number of lights
  for (int i = 0; i < numLightsD; ++i) {
    digitalWrite(channelDPins[i], LOW);  // Turn on the lights
  }
  for (int i = numLightsD; i < sizeof(channelDPins) / sizeof(channelDPins[0]); ++i) {
    digitalWrite(channelDPins[i], HIGH);  // Turn off the remaining lights
  }
}
COMPILER ERROR:
/Users/skywiresolar/Documents/Arduino/Load_Bank_Software_10.57A.M._5.15.2024/Load_Bank_Software_10.57A.M._5.15.2024.ino: In function 'void loop()':
/Users/skywiresolar/Documents/Arduino/Load_Bank_Software_10.57A.M._5.15.2024/Load_Bank_Software_10.57A.M._5.15.2024.ino:12:30: error: call to 'PureAnalogPin::operator int' declared with attribute error: Change me to a #define
 #define CURRENT_SENSOR_PIN_A A9
                              ^
/Users/skywiresolar/Documents/Arduino/Load_Bank_Software_10.57A.M._5.15.2024/Load_Bank_Software_10.57A.M._5.15.2024.ino:12:30: note: in definition of macro 'CURRENT_SENSOR_PIN_A'
 #define CURRENT_SENSOR_PIN_A A9
                              ^~
/Users/skywiresolar/Documents/Arduino/Load_Bank_Software_10.57A.M._5.15.2024/Load_Bank_Software_10.57A.M._5.15.2024.ino:13:30: error: call to 'PureAnalogPin::operator int' declared with attribute error: Change me to a #define
 #define CURRENT_SENSOR_PIN_B A10
                              ^
/Users/skywiresolar/Documents/Arduino/Load_Bank_Software_10.57A.M._5.15.2024/Load_Bank_Software_10.57A.M._5.15.2024.ino:13:30: note: in definition of macro 'CURRENT_SENSOR_PIN_B'
 #define CURRENT_SENSOR_PIN_B A10
                              ^~~
/Users/skywiresolar/Documents/Arduino/Load_Bank_Software_10.57A.M._5.15.2024/Load_Bank_Software_10.57A.M._5.15.2024.ino:14:30: error: call to 'PureAnalogPin::operator int' declared with attribute error: Change me to a #define
 #define CURRENT_SENSOR_PIN_C A11
                              ^
/Users/skywiresolar/Documents/Arduino/Load_Bank_Software_10.57A.M._5.15.2024/Load_Bank_Software_10.57A.M._5.15.2024.ino:14:30: note: in definition of macro 'CURRENT_SENSOR_PIN_C'
 #define CURRENT_SENSOR_PIN_C A11
                              ^~~

exit status 1

Compilation error: call to 'PureAnalogPin::operator int' declared with attribute error: Change me to a #define
PureAnalogPin  A8(0);
PureAnalogPin  A9(1);
PureAnalogPin  A10(2);
PureAnalogPin  A11(3);

they can not be assigned to an int

Thank you for this, that helps a lot and makes sense. Do you know another way around this? I have filled up the analog pins on my board and have no extras, I tried using an I2C ADS1115 16-bit ADC but had a ton of issues. trying to share it on the default pins 20,21 SDA, SCL lines. I couldnt ever figure out how to get the SCL1 and SDA1 for wire1 initialized to try out that other I2C line. Thank you for your quick and precise answer on the A9-A11 answer.

can you switch A12 to A8?
then change to

float readACCurrent(PureAnalogPin pin) {

and

  currentA = readACCurrent(CURRENT_SENSOR_PIN_A);

Made those tweaks and that passed the compiler pre check, I went to upload and after uploading it is causing the board to crash with the flashing red LED. I double tapped the reset button and uploaded a different sketch and all is well. but this sketch in particular sends my board into a red flashing crash state? Do you have any thoughts based on the code? also you were spot on with the fixes, thank you for that.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Define constants for voltage reference and ADC resolution
#define VOLTAGE_REFERENCE 3.3    // Arduino operating at 3.3V
#define ADC_RESOLUTION 1023      // Resolution of Arduino ADC for 3.3V
#define ZERO_CURRENT_VOLTAGE (VOLTAGE_REFERENCE / 2) // 1.65V for zero current
#define SENSITIVITY 0.044        // Sensitivity in V/A
#define NUM_SAMPLES 100          // Number of samples to average for RMS calculation

// Declare PureAnalogPin for current sensor pins
PureAnalogPin CURRENT_SENSOR_PIN_A = A9;
PureAnalogPin CURRENT_SENSOR_PIN_B = A10;
PureAnalogPin CURRENT_SENSOR_PIN_C = A11;
PureAnalogPin CURRENT_SENSOR_PIN_D = A12;
const int INVERTER_AC_SENSE = A6;

// Global variable to store the inverter voltage
double INVERTER_VAC = 0;

// Global variables to store current and wattage for each channel
float currentA, currentB, currentC, currentD;
double wattageA, wattageB, wattageC, wattageD;

// Create an array of LiquidCrystal_I2C objects for each address
LiquidCrystal_I2C lcds[] = {
  LiquidCrystal_I2C(0x20, 16, 2),  // CHANNEL A TOTALS
  LiquidCrystal_I2C(0x21, 16, 2),  // PV WATT/INV AC OUT
  LiquidCrystal_I2C(0x22, 16, 2),  // PV WATTS
  LiquidCrystal_I2C(0x23, 16, 2),  // CHANNEL B TOTALS
  LiquidCrystal_I2C(0x24, 16, 2),  // CHANNEL C TOTALS
  LiquidCrystal_I2C(0x25, 16, 2),  // CHANNEL D TOTALS
  LiquidCrystal_I2C(0x26, 16, 2),  // INVERTER W
  LiquidCrystal_I2C(0x27, 16, 2)   // AC-IN WATTS
};
const int numLcds = sizeof(lcds) / sizeof(lcds[0]); // Number of LCDs

// Pin declarations for buttons, receptacles, potentiometers, and light channels
#define buttonPin1A 9  // TURNS ON RECEPTACLES CHANNEL A
#define buttonPin1B 8  // TURNS ON RECEPTACLES CHANNEL B
#define buttonPin1C 7  // TURNS ON RECEPTACLES CHANNEL C
#define buttonPin1D 6  // TURNS ON RECEPTACLES CHANNEL D
#define receptaclesChannel_B 43  // RELAY THAT ACTIVATES THE OUTLETS CHANNEL B
#define receptaclesChannel_C 5  // RELAY THAT ACTIVATES THE OUTLETS CHANNEL C
#define receptaclesChannel_D 19  // RELAY THAT ACTIVATES THE OUTLETS CHANNEL D
#define receptaclesChannel_A 32  // RELAY THAT ACTIVATES THE OUTLETS CHANNEL A
#define potPinA A0  // CHANNEL A 10K POTENTIOMETER CONTROLS CHANNEL A LIGHTBULBS PINS 22-31
#define startLightA 22
#define endLightA 31
#define potPinB A1  // CHANNEL B 10K POTENTIOMETER CONTROLS CHANNEL B LIGHTBULBS PINS 33-42
#define startLightB 33
#define endLightB 42
#define potPinC A2  // CHANNEL C 10K POTENTIOMETER CONTROLS CHANNEL C LIGHTBULBS PINS 44-53
#define startLightC 44
#define endLightC 53
#define potPinD A3  // CHANNEL D 10K POTENTIOMETER CONTROLS CHANNEL D LIGHTBULBS PINS 4, 3, 2, 1, 0, 14, 15, 16, 17, 18
const int channelDPins[] = {4, 3, 2, 1, 0, 14, 15, 16, 17, 18};

// Function prototypes
float readACCurrent(PureAnalogPin pin);
void readSensorAndDisplay();
double calculateWattage(double current, double voltage);
void controlReceptacles();
void controlLights();
void updateLights(int potPin, int startLight, int endLight);
void updateChannelDLights();

void setup() {
  Wire.begin();  // Start I2C communication on Pins 20 and 21
  Serial.begin(9600);

  // Initialize each LCD
  for (int i = 0; i < numLcds; i++) {
    lcds[i].begin();
    lcds[i].backlight();
    lcds[i].clear();

    // Prepare initial text for each LCD and update
    String line1, line2;
    switch (i) {
      case 0:
        line1 = "CHANNEL A TOTALS";
        line2 = "WATTS";
        break;
      case 1:
        line1 = "PV WATT/INV AC OUT";
        line2 = "EFFICIENCY %";
        break;
      case 2:
        line1 = "PV WATTS";
        line2 = "VDC       A";
        break;
      case 3:
        line1 = "CHANNEL B TOTALS";
        line2 = "WATTS";
        break;
      case 4:
        line1 = "CHANNEL C TOTALS";
        line2 = "WATTS";
        break;
      case 5:
        line1 = "CHANNEL D TOTALS";
        line2 = "WATTS";
        break;
      case 6:
        line1 = "INVERTER W";
        line2 = "VAC       A";
        break;
      case 7:
        line1 = "AC-IN WATTS";
        line2 = "VAC       A";
        break;
    }
    lcds[i].setCursor(0, 0);
    lcds[i].print(line1);
    lcds[i].setCursor(0, 1);
    lcds[i].print(line2);
  }

  // Set button pins as input
  pinMode(buttonPin1A, INPUT);
  pinMode(buttonPin1B, INPUT);
  pinMode(buttonPin1C, INPUT);
  pinMode(buttonPin1D, INPUT);

  // Set receptacle pins as output
  pinMode(receptaclesChannel_B, OUTPUT);
  pinMode(receptaclesChannel_C, OUTPUT);
  pinMode(receptaclesChannel_D, OUTPUT);
  pinMode(receptaclesChannel_A, OUTPUT);

  // Initially turn off the receptacles
  digitalWrite(receptaclesChannel_B, HIGH);
  digitalWrite(receptaclesChannel_C, HIGH);
  digitalWrite(receptaclesChannel_D, HIGH);
  digitalWrite(receptaclesChannel_A, HIGH);

  // Set light pins for all channels as output and turn them off
  for (int pin = startLightA; pin <= endLightA; ++pin) {
    pinMode(pin, OUTPUT);
    digitalWrite(pin, HIGH);
  }
  for (int pin = startLightB; pin <= endLightB; ++pin) {
    pinMode(pin, OUTPUT);
    digitalWrite(pin, HIGH);
  }
  for (int pin = startLightC; pin <= endLightC; ++pin) {
    pinMode(pin, OUTPUT);
    digitalWrite(pin, HIGH);
  }
  for (int i = 0; i < sizeof(channelDPins) / sizeof(channelDPins[0]); ++i) {
    pinMode(channelDPins[i], OUTPUT);
    digitalWrite(channelDPins[i], HIGH);
  }
}

void loop() {
  // Read the inverter AC voltage
  readSensorAndDisplay();

  // Read currents for each channel using PureAnalogPin type
  currentA = readACCurrent(CURRENT_SENSOR_PIN_A);
  currentB = readACCurrent(CURRENT_SENSOR_PIN_B);
  currentC = readACCurrent(CURRENT_SENSOR_PIN_C);
  currentD = readACCurrent(CURRENT_SENSOR_PIN_D);

  // Calculate wattages for each channel
  wattageA = calculateWattage(currentA, INVERTER_VAC);
  wattageB = calculateWattage(currentB, INVERTER_VAC);
  wattageC = calculateWattage(currentC, INVERTER_VAC);
  wattageD = calculateWattage(currentD, INVERTER_VAC);

  // Display the wattages on corresponding LCDs (example for CHANNEL A TOTALS)
  lcds[0].setCursor(0, 1); // Set cursor for display
  lcds[0].print(wattageA); // Display wattage for Channel A

  // Other control functions
  controlReceptacles();
  controlLights();

  delay(1000);  // Delay for 1 second before next read
}

/**
 * Reads the AC current from the specified pin.
 *
 * @param pin The analog pin to read the current from.
 * @return The RMS current in Amperes.
 */
float readACCurrent(PureAnalogPin pin) {
  float sum = 0;
  for (int i = 0; i < NUM_SAMPLES; i++) {
    int sensorValue = analogRead(pin);  // Read the sensor value
    float voltage = sensorValue * (VOLTAGE_REFERENCE / ADC_RESOLUTION);  // Convert to voltage
    float current = (voltage - ZERO_CURRENT_VOLTAGE) / SENSITIVITY;      // Convert voltage to current
    sum += current * current;  // Sum the squares of currents
    delay(1);  // Delay for 1 millisecond between samples
  }
  float meanSquare = sum / NUM_SAMPLES;  // Calculate the mean square of current
  return sqrt(meanSquare);  // Return the RMS current (square root of mean square)
}

/**
 * Calculates the wattage from the current and voltage.
 *
 * @param current The current in Amperes.
 * @param voltage The voltage in Volts.
 * @return The wattage in Watts.
 */
double calculateWattage(double current, double voltage) {
  return current * voltage;
}

/**
 * Reads the sensor value from INVERTER_AC_SENSE and updates the global variable INVERTER_VAC.
 * Displays the average RMS voltage on the LCD.
 */
void readSensorAndDisplay() {
  static int index = 0;  // Current index in the circular buffer
  static double recentValues[10];  // Circular buffer to store recent RMS values
  static double sum = 0;  // Running sum of values in the buffer
  static int count = 0;  // Count of values in the buffer
  const int windowSize = 10;  // Number of values to average

  int sensorValue = 0;
  int maxV = 0;
  double VmaxD = 0;
  double Veff = 0;
  double avgVeff = 0;
  const double originalScaleFactor = 34.0;
  const double observedRMS = 77.0;
  const double expectedRMS = 120.0;

  // Calculate new scale factor
  double newScaleFactor = originalScaleFactor * (expectedRMS / observedRMS);

  // Read sensor values and store the maximum
  for (int i = 0; i < 100; i++) {
    sensorValue = analogRead(INVERTER_AC_SENSE);
    if (sensorValue > maxV) {
      maxV = sensorValue;
    }
    delay(1);
  }

  // Calculate RMS voltage
  VmaxD = (maxV * 5.0 / 1023.0) * newScaleFactor;
  Veff = VmaxD / sqrt(2);

  // Update the circular buffer and adjust the running sum
  sum -= recentValues[index];  // Subtract the old value from the sum (it's zero if not yet filled)
  recentValues[index] = Veff;  // Insert new RMS value
  sum += Veff;  // Add the new value to the sum

  index = (index + 1) % windowSize;  // Move to the next index, wrap around using modulo

  if (count < windowSize) {
    count++;  // Increase count until the buffer is filled
  }

  // Calculate the average of the values in the buffer
  if (count == windowSize) {
    avgVeff = sum / windowSize;  // Only calculate average if the buffer is full
  } else {
    avgVeff = sum / count;  // Calculate using the count if buffer not yet full
  }

  // Update global variable for INVERTER_VAC
  INVERTER_VAC = avgVeff;

  // Display the average RMS voltage on LCD
  lcds[6].setCursor(3, 1); // Set cursor for display (column 3, line 1)
  lcds[6].print(INVERTER_VAC);
}

/**
 * Controls the state of the receptacles based on button inputs.
 */
void controlReceptacles() {
  int buttonState1A = digitalRead(buttonPin1A);
  digitalWrite(receptaclesChannel_A, buttonState1A ? LOW : HIGH);
  int buttonState1B = digitalRead(buttonPin1B);
  digitalWrite(receptaclesChannel_B, buttonState1B ? LOW : HIGH);
  int buttonState1C = digitalRead(buttonPin1C);
  digitalWrite(receptaclesChannel_C, buttonState1C ? LOW : HIGH);
  int buttonState1D = digitalRead(buttonPin1D);
  digitalWrite(receptaclesChannel_D, buttonState1D ? LOW : HIGH);
}

/**
 * Controls the lights based on potentiometer inputs.
 */
void controlLights() {
  updateLights(potPinA, startLightA, endLightA);
  updateLights(potPinB, startLightB, endLightB);
  updateLights(potPinC, startLightC, endLightC);
  updateChannelDLights();
}

/**
 * Updates the state of the lights in the specified range based on the potentiometer input.
 *
 * @param potPin The analog pin connected to the potentiometer.
 * @param startLight The starting pin of the light range.
 * @param endLight The ending pin of the light range.
 */
void updateLights(int potPin, int startLight, int endLight) {
  int potValue = analogRead(potPin);  // Read the potentiometer value
  int numLights = map(potValue, 0, 1023, 0, endLight - startLight + 1);  // Map the value to the number of lights
  for (int pin = startLight; pin < startLight + numLights; ++pin) {
    digitalWrite(pin, LOW);  // Turn on the lights
  }
  for (int pin = startLight + numLights; pin <= endLight; ++pin) {
    digitalWrite(pin, HIGH);  // Turn off the remaining lights
  }
}

/**
 * Updates the state of the lights in channel D based on the potentiometer input.
 */
void updateChannelDLights() {
  int potValueD = analogRead(potPinD);  // Read the potentiometer value
  int numLightsD = map(potValueD, 0, 1023, 0, sizeof(channelDPins) / sizeof(channelDPins[0]));  // Map the value to the number of lights
  for (int i = 0; i < numLightsD; ++i) {
    digitalWrite(channelDPins[i], LOW);  // Turn on the lights
  }
  for (int i = numLightsD; i < sizeof(channelDPins) / sizeof(channelDPins[0]); ++i) {
    digitalWrite(channelDPins[i], HIGH);  // Turn off the remaining lights
  }
}


try loat readACCurrent(PureAnalogPin& pin);

I added the & symbol, it looked like it was gonna work because the flashing red led happened in a bout 5 seconds instead of the original 2 seconds.

I tried commenting out this section and running and the program doesnt crash when I do this

/* currentA = readACCurrent(CURRENT_SENSOR_PIN_A);
currentB = readACCurrent(CURRENT_SENSOR_PIN_B);
currentC = readACCurrent(CURRENT_SENSOR_PIN_C);
currentD = readACCurrent(CURRENT_SENSOR_PIN_D);
*/

I dont know if this helps narrow it down to something?

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Define constants for voltage reference and ADC resolution
#define VOLTAGE_REFERENCE 3.3    // Arduino operating at 3.3V
#define ADC_RESOLUTION 1023      // Resolution of Arduino ADC for 3.3V
#define ZERO_CURRENT_VOLTAGE (VOLTAGE_REFERENCE / 2) // 1.65V for zero current
#define SENSITIVITY 0.044        // Sensitivity in V/A
#define NUM_SAMPLES 100          // Number of samples to average for RMS calculation

// Declare PureAnalogPin for current sensor pins
PureAnalogPin CURRENT_SENSOR_PIN_A = A9;
PureAnalogPin CURRENT_SENSOR_PIN_B = A10;
PureAnalogPin CURRENT_SENSOR_PIN_C = A11;
PureAnalogPin CURRENT_SENSOR_PIN_D = A12;
const int INVERTER_AC_SENSE = A6;

// Global variable to store the inverter voltage
double INVERTER_VAC = 0;

// Global variables to store current and wattage for each channel
float currentA, currentB, currentC, currentD;
double wattageA, wattageB, wattageC, wattageD;

// Create an array of LiquidCrystal_I2C objects for each address
LiquidCrystal_I2C lcds[] = {
  LiquidCrystal_I2C(0x20, 16, 2),  // CHANNEL A TOTALS
  LiquidCrystal_I2C(0x21, 16, 2),  // PV WATT/INV AC OUT
  LiquidCrystal_I2C(0x22, 16, 2),  // PV WATTS
  LiquidCrystal_I2C(0x23, 16, 2),  // CHANNEL B TOTALS
  LiquidCrystal_I2C(0x24, 16, 2),  // CHANNEL C TOTALS
  LiquidCrystal_I2C(0x25, 16, 2),  // CHANNEL D TOTALS
  LiquidCrystal_I2C(0x26, 16, 2),  // INVERTER W
  LiquidCrystal_I2C(0x27, 16, 2)   // AC-IN WATTS
};
const int numLcds = sizeof(lcds) / sizeof(lcds[0]); // Number of LCDs

// Pin declarations for buttons, receptacles, potentiometers, and light channels
#define buttonPin1A 9  // TURNS ON RECEPTACLES CHANNEL A
#define buttonPin1B 8  // TURNS ON RECEPTACLES CHANNEL B
#define buttonPin1C 7  // TURNS ON RECEPTACLES CHANNEL C
#define buttonPin1D 6  // TURNS ON RECEPTACLES CHANNEL D
#define receptaclesChannel_B 43  // RELAY THAT ACTIVATES THE OUTLETS CHANNEL B
#define receptaclesChannel_C 5  // RELAY THAT ACTIVATES THE OUTLETS CHANNEL C
#define receptaclesChannel_D 19  // RELAY THAT ACTIVATES THE OUTLETS CHANNEL D
#define receptaclesChannel_A 32  // RELAY THAT ACTIVATES THE OUTLETS CHANNEL A
#define potPinA A0  // CHANNEL A 10K POTENTIOMETER CONTROLS CHANNEL A LIGHTBULBS PINS 22-31
#define startLightA 22
#define endLightA 31
#define potPinB A1  // CHANNEL B 10K POTENTIOMETER CONTROLS CHANNEL B LIGHTBULBS PINS 33-42
#define startLightB 33
#define endLightB 42
#define potPinC A2  // CHANNEL C 10K POTENTIOMETER CONTROLS CHANNEL C LIGHTBULBS PINS 44-53
#define startLightC 44
#define endLightC 53
#define potPinD A3  // CHANNEL D 10K POTENTIOMETER CONTROLS CHANNEL D LIGHTBULBS PINS 4, 3, 2, 1, 0, 14, 15, 16, 17, 18
const int channelDPins[] = {4, 3, 2, 1, 0, 14, 15, 16, 17, 18};

// Timing variables
unsigned long previousMillis = 0;
const long interval = 1000;  // Interval for reading and displaying data (1 second)

// Function prototypes
float readACCurrent(PureAnalogPin& pin);
void readSensorAndDisplay();
double calculateWattage(double current, double voltage);
void controlReceptacles();
void controlLights();
void updateLights(int potPin, int startLight, int endLight);
void updateChannelDLights();

void setup() {
  Wire.begin();  // Start I2C communication on Pins 20 and 21
  Serial.begin(9600);

  // Initialize each LCD
  for (int i = 0; i < numLcds; i++) {
    lcds[i].begin();
    lcds[i].backlight();
    lcds[i].clear();

    // Prepare initial text for each LCD and update
    String line1, line2;
    switch (i) {
      case 0:
        line1 = "CHANNEL A TOTALS";
        line2 = "WATTS";
        break;
      case 1:
        line1 = "PV WATT/INV AC OUT";
        line2 = "EFFICIENCY %";
        break;
      case 2:
        line1 = "PV WATTS";
        line2 = "VDC       A";
        break;
      case 3:
        line1 = "CHANNEL B TOTALS";
        line2 = "WATTS";
        break;
      case 4:
        line1 = "CHANNEL C TOTALS";
        line2 = "WATTS";
        break;
      case 5:
        line1 = "CHANNEL D TOTALS";
        line2 = "WATTS";
        break;
      case 6:
        line1 = "INVERTER W";
        line2 = "VAC       A";
        break;
      case 7:
        line1 = "AC-IN WATTS";
        line2 = "VAC       A";
        break;
    }
    lcds[i].setCursor(0, 0);
    lcds[i].print(line1);
    lcds[i].setCursor(0, 1);
    lcds[i].print(line2);
  }

  // Set button pins as input
  pinMode(buttonPin1A, INPUT);
  pinMode(buttonPin1B, INPUT);
  pinMode(buttonPin1C, INPUT);
  pinMode(buttonPin1D, INPUT);

  // Set receptacle pins as output
  pinMode(receptaclesChannel_B, OUTPUT);
  pinMode(receptaclesChannel_C, OUTPUT);
  pinMode(receptaclesChannel_D, OUTPUT);
  pinMode(receptaclesChannel_A, OUTPUT);

  // Initially turn off the receptacles
  digitalWrite(receptaclesChannel_B, HIGH);
  digitalWrite(receptaclesChannel_C, HIGH);
  digitalWrite(receptaclesChannel_D, HIGH);
  digitalWrite(receptaclesChannel_A, HIGH);

  // Set light pins for all channels as output and turn them off
  for (int pin = startLightA; pin <= endLightA; ++pin) {
    pinMode(pin, OUTPUT);
    digitalWrite(pin, HIGH);
  }
  for (int pin = startLightB; pin <= endLightB; ++pin) {
    pinMode(pin, OUTPUT);
    digitalWrite(pin, HIGH);
  }
  for (int pin = startLightC; pin <= endLightC; ++pin) {
    pinMode(pin, OUTPUT);
    digitalWrite(pin, HIGH);
  }
  for (int i = 0; i < sizeof(channelDPins) / sizeof(channelDPins[0]); ++i) {
    pinMode(channelDPins[i], OUTPUT);
    digitalWrite(channelDPins[i], HIGH);
  }
}

void loop() {
  unsigned long currentMillis = millis();

  // Check if the interval has passed
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    // Read the inverter AC voltage
    readSensorAndDisplay();

    // Read currents for each channel using PureAnalogPin type
   /* currentA = readACCurrent(CURRENT_SENSOR_PIN_A);
    currentB = readACCurrent(CURRENT_SENSOR_PIN_B);
    currentC = readACCurrent(CURRENT_SENSOR_PIN_C);
    currentD = readACCurrent(CURRENT_SENSOR_PIN_D);
    */


    // Calculate wattages for each channel
    wattageA = calculateWattage(currentA, INVERTER_VAC);
    wattageB = calculateWattage(currentB, INVERTER_VAC);
    wattageC = calculateWattage(currentC, INVERTER_VAC);
    wattageD = calculateWattage(currentD, INVERTER_VAC);

    // Display the wattages on corresponding LCDs (example for CHANNEL A TOTALS)
    lcds[0].setCursor(0, 1); // Set cursor for display
    lcds[0].print(wattageA); // Display wattage for Channel A

    // Other control functions
    controlReceptacles();
    controlLights();
  }
}

/**
 * Reads the AC current from the specified pin.
 *
 * @param pin The analog pin to read the current from.
 * @return The RMS current in Amperes.
 */
float readACCurrent(PureAnalogPin& pin) {
  float sum = 0;
  unsigned long sampleStartMillis = millis();
  int samplesTaken = 0;

  while (samplesTaken < NUM_SAMPLES) {
    if (millis() - sampleStartMillis >= 1) {
      sampleStartMillis = millis();
      int sensorValue = analogRead(pin);  // Read the sensor value
      float voltage = sensorValue * (VOLTAGE_REFERENCE / ADC_RESOLUTION);  // Convert to voltage
      float current = (voltage - ZERO_CURRENT_VOLTAGE) / SENSITIVITY;      // Convert voltage to current
      sum += current * current;  // Sum the squares of currents
      samplesTaken++;
    }
  }

  float meanSquare = sum / samplesTaken;  // Calculate the mean square of current
  return sqrt(meanSquare);  // Return the RMS current (square root of mean square)
}

/**
 * Calculates the wattage from the current and voltage.
 *
 * @param current The current in Amperes.
 * @param voltage The voltage in Volts.
 * @return The wattage in Watts.
 */
double calculateWattage(double current, double voltage) {
  return current * voltage;
}

/**
 * Reads the sensor value from INVERTER_AC_SENSE and updates the global variable INVERTER_VAC.
 * Displays the average RMS voltage on the LCD.
 */
void readSensorAndDisplay() {
  static int index = 0;  // Current index in the circular buffer
  static double recentValues[10];  // Circular buffer to store recent RMS values
  static double sum = 0;  // Running sum of values in the buffer
  static int count = 0;  // Count of values in the buffer
  const int windowSize = 10;  // Number of values to average

  int sensorValue = 0;
  int maxV = 0;
  double VmaxD = 0;
  double Veff = 0;
  double avgVeff = 0;
  const double originalScaleFactor = 34.0;
  const double observedRMS = 77.0;
  const double expectedRMS = 120.0;

  // Calculate new scale factor
  double newScaleFactor = originalScaleFactor * (expectedRMS / observedRMS);

  // Read sensor values and store the maximum
  unsigned long readStartMillis = millis();
  int samplesTaken = 0;
  while (samplesTaken < 100) {
    if (millis() - readStartMillis >= 1) {
      readStartMillis = millis();
      sensorValue = analogRead(INVERTER_AC_SENSE);
      if (sensorValue > maxV) {
        maxV = sensorValue;
      }
      samplesTaken++;
    }
  }

  // Calculate RMS voltage
  VmaxD = (maxV * 5.0 / 1023.0) * newScaleFactor;
  Veff = VmaxD / sqrt(2);

  // Update the circular buffer and adjust the running sum
  sum -= recentValues[index];  // Subtract the old value from the sum (it's zero if not yet filled)
  recentValues[index] = Veff;  // Insert new RMS value
  sum += Veff;  // Add the new value to the sum

  index = (index + 1) % windowSize;  // Move to the next index, wrap around using modulo

  if (count < windowSize) {
    count++;  // Increase count until the buffer is filled
  }

  // Calculate the average of the values in the buffer
  if (count == windowSize) {
    avgVeff = sum / windowSize;  // Only calculate average if the buffer is full
  } else {
    avgVeff = sum / count;  // Calculate using the count if buffer not yet full
  }

  // Update global variable for INVERTER_VAC
  INVERTER_VAC = avgVeff;

  // Display the average RMS voltage on LCD
  lcds[6].setCursor(3, 1); // Set cursor for display (column 3, line 1)
  lcds[6].print(INVERTER_VAC);
}

/**
 * Controls the state of the receptacles based on button inputs.
 */
void controlReceptacles() {
  int buttonState1A = digitalRead(buttonPin1A);
  digitalWrite(receptaclesChannel_A, buttonState1A ? LOW : HIGH);
  int buttonState1B = digitalRead(buttonPin1B);
  digitalWrite(receptaclesChannel_B, buttonState1B ? LOW : HIGH);
  int buttonState1C = digitalRead(buttonPin1C);
  digitalWrite(receptaclesChannel_C, buttonState1C ? LOW : HIGH);
  int buttonState1D = digitalRead(buttonPin1D);
  digitalWrite(receptaclesChannel_D, buttonState1D ? LOW : HIGH);
}

/**
 * Controls the lights based on potentiometer inputs.
 */
void controlLights() {
  updateLights(potPinA, startLightA, endLightA);
  updateLights(potPinB, startLightB, endLightB);
  updateLights(potPinC, startLightC, endLightC);
  updateChannelDLights();
}

/**
 * Updates the state of the lights in the specified range based on the potentiometer input.
 *
 * @param potPin The analog pin connected to the potentiometer.
 * @param startLight The starting pin of the light range.
 * @param endLight The ending pin of the light range.
 */
void updateLights(int potPin, int startLight, int endLight) {
  int potValue = analogRead(potPin);  // Read the potentiometer value
  int numLights = map(potValue, 0, 1023, 0, endLight - startLight + 1);  // Map the value to the number of lights
  for (int pin = startLight; pin < startLight + numLights; ++pin) {
    digitalWrite(pin, LOW);  // Turn on the lights
  }
  for (int pin = startLight + numLights; pin <= endLight; ++pin) {
    digitalWrite(pin, HIGH);  // Turn off the remaining lights
  }
}

/**
 * Updates the state of the lights in channel D based on the potentiometer input.
 */
void updateChannelDLights() {
  int potValueD = analogRead(potPinD);  // Read the potentiometer value
  int numLightsD = map(potValueD, 0, 1023, 0, sizeof(channelDPins) / sizeof(channelDPins[0]));  // Map the value to the number of lights
  for (int i = 0; i < numLightsD; ++i) {
    digitalWrite(channelDPins[i], LOW);  // Turn on the lights
  }
  for (int i = numLightsD; i < sizeof(channelDPins) / sizeof(channelDPins[0]); ++i) {
    digitalWrite(channelDPins[i], HIGH);  // Turn off the remaining lights
  }
}