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:
- get the Light bulbs to operate off the potentiometer values,
- Get the 4 buttons to control 4 outlet relays
- Get the analog pin A6 to convert digital signal from the Grove AC sensor into a value that I print on LCD 6
- Setup I2C comms for 8 of the 9 LCD displays
- 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