So I've been digging into this for a while now, and I'm trying to come up with a good solution but am currently stumped, and figured I'd go right to the source.
I have a project where I want to attach more than one HLW8012 board/chip to a single Arduino, then every interval return the values for all of them. In short, a PDU, more than a single smart plug. And for the sake of argument I have an Arduino with at least 4 PWM inputs (so not an Uno). So I create an array of instances of the HLW8012 class inside a simple struct like so:
struct Sensor {
String label; // Sensor label/name
HLW8012* hlw; // Class instance of HLW8012 library
int sel_pin; // Digital output pin for sel
int cf1_pin; // Digital PWM-capable input pin for cf1
int cf_pin; // Digital PWM-capable input pin for cf
};
const Sensor SensorDatabase[] = {
(Sensor) { "01A", new HLW8012, 1, 2, 3 },
(Sensor) { "01B", new HLW8012, 4, 5, 6 }
};
const int SensorCount = 2;
I then initialize them in a loop:
void setup() {
// Initialize the HLW8012 module for each sensor entry
for (int s = 0; s < SensorCount; s++) {
// Initialize HLW8012 class instance
SensorDatabase[s].hlw->begin(SensorDatabase[s].cf_pin, SensorDatabase[s].cf1_pin, SensorDatabase[s].sel_pin, HIGH, true);
// Set the nominal value of the resistors
SensorDatabase[s].hlw->setResistors(CURRENT_RESISTOR, VOLTAGE_RESISTOR_US, VOLTAGE_RESISTOR_DS);
// ???????????
}
}
The issue comes with the attachInterrupt
calls, which I presume I would want to do in the ?????
bit above. One fairly obvious but non-working attempt:
attachInterrupt(digitalPinToInterrupt(SensorDatabase[s].cf_pin), SensorDatabase[s].hlw->cf_interrupt, CHANGE);
attachInterrupt(digitalPinToInterrupt(SensorDatabase[s].cf1_pin), SensorDatabase[s].hlw->cf1_interrupt, CHANGE);
error: invalid use of non-static member function
attachInterrupt(digitalPinToInterrupt(SensorDatabase[s].cf_pin), SensorDatabase[s].hlw->cf_interrupt, CHANGE);
error: invalid use of non-static member function
attachInterrupt(digitalPinToInterrupt(SensorDatabase[s].cf1_pin), SensorDatabase[s].hlw->cf1_interrupt, CHANGE);
Since these have to take a pointer to a function with no arguments that returns a void
, I can't find a way to do this - all of the methods seem to require these to be static
functions, but doing so seems non-trivial. I've tried looking for other more general solution, but a solid number of them recommend workarounds that don't seem to go anywhere (stuff like std::bind
, using various constructors there, and of course the wrapper function idea that is used in the interrupts example but is hard to scale like this).
Does anyone have any advice about this specific library, and what if anything I might need to do to it to make this work how I'd like - initialize multiple instance of the class each bound to interrupts on different pins in a semi-dynamic (array) way?