How can I include MyMessage object in my own class?
-
Dear all, I have been trying to change my Arduino Mega project controlling 16 relays for Light on/off. The board is working standalone as gateway for Domoticz. The reason is, I want to have bullet proof Smart Home with only one point of failture - in this case arduino Mega. Untill now I was separately creating every button/relay, so a lot of code. I though it would be nice, to create a class switch, and then create a array of 16 objects of class switch. This will make the code looking much better. The problem is, I need to create object MyMessage in my own class switch, how can I do it? The code is compiling until I declare MyMessage msg(child_id, V_LIGHT) inside the class switch. I will leave code for single switch and my code trying convert it to class object.
Original working code:
// Enable debug prints to serial monitor #define MY_DEBUG // Enable and select radio type attached //#define MY_RADIO_NRF24 //#define MY_RADIO_RFM69 // Set LOW transmit power level as default, if you have an amplified NRF-module and // power your radio separately with a good regulator you can turn up PA level. //#define MY_RF24_PA_LEVEL RF24_PA_LOW // Enable serial gateway #define MY_GATEWAY_SERIAL // Define a lower baud rate for Arduino's running on 8 MHz (Arduino Pro Mini 3.3V & SenseBender) #if F_CPU == 8000000L #define MY_BAUD_RATE 38400 #endif // Flash leds on rx/tx/err // #define MY_LEDS_BLINKING_FEATURE // Set blinking period // #define MY_DEFAULT_LED_BLINK_PERIOD 300 // Inverses the behavior of leds // #define MY_WITH_LEDS_BLINKING_INVERSE // Enable inclusion mode #define MY_INCLUSION_MODE_FEATURE // Enable Inclusion mode button on gateway #define MY_INCLUSION_BUTTON_FEATURE // Inverses behavior of inclusion button (if using external pullup) //#define MY_INCLUSION_BUTTON_EXTERNAL_PULLUP // Set inclusion mode duration (in seconds) #define MY_INCLUSION_MODE_DURATION 60 // Digital pin used for inclusion mode button #define MY_INCLUSION_MODE_BUTTON_PIN 3 // Uncomment to override default HW configurations //#define MY_DEFAULT_ERR_LED_PIN 4 // Error led pin //#define MY_DEFAULT_RX_LED_PIN 6 // Receive led pin //#define MY_DEFAULT_TX_LED_PIN 5 // the PCB, on board LED #include <SPI.h> #include <MySensors.h> #include <Bounce2.h> // Enable repeater functionality for this node #define MY_REPEATER_FEATURE #define RELAY_1 4 // Arduino Digital I/O pin number for first relay (second on pin+1 etc) #define NUMBER_OF_RELAYS 1 // Total number of attached relays #define RELAY_ON 1 // GPIO value to write to turn on attached relay #define RELAY_OFF 0 // GPIO value to write to turn off attached relay #define BUTTON_PIN A1 void before() { for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS;sensor++, pin++) { // Then set relay pins in output mode pinMode(pin, OUTPUT); // Set relay to last known state (using eeprom storage) digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF); } } Bounce debouncer = Bounce(); void setup() { // Setup locally attached sensors delay(10000); // Setup the button. pinMode(BUTTON_PIN, INPUT_PULLUP); // After setting up the button, setup debouncer. debouncer.attach(BUTTON_PIN); debouncer.interval(5); //presentation(); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("Relay", "1.0"); for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS;sensor++, pin++) { // Register all sensors to gw (they will be created as child devices) present(sensor, S_LIGHT); } } MyMessage msg(1, V_LIGHT); void loop() { // Send locally attached sensor data here if (debouncer.update()) { // Get the update value. int value = debouncer.read(); // Send in the new value. if(value == LOW){ saveState(1, !loadState(1)); digitalWrite(RELAY_1, loadState(1)?RELAY_ON:RELAY_OFF); send(msg.set(loadState(1))); } } } void receive(const MyMessage &message) { // We only expect one type of message from controller. But we better check anyway. if (message.type==V_LIGHT) { // Change relay state digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF); // Store state in eeprom saveState(message.sensor, message.getBool()); // Write some debug info Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); } }
Here the new object oriented version:
// Enable debug prints to serial monitor #define MY_DEBUG // Enable and select radio type attached //#define MY_RADIO_NRF24 //#define MY_RADIO_RFM69 // Set LOW transmit power level as default, if you have an amplified NRF-module and // power your radio separately with a good regulator you can turn up PA level. //#define MY_RF24_PA_LEVEL RF24_PA_LOW // Enable serial gateway #define MY_GATEWAY_SERIAL // Define a lower baud rate for Arduino's running on 8 MHz (Arduino Pro Mini 3.3V & SenseBender) #if F_CPU == 8000000L #define MY_BAUD_RATE 38400 #endif // Flash leds on rx/tx/err // #define MY_LEDS_BLINKING_FEATURE // Set blinking period // #define MY_DEFAULT_LED_BLINK_PERIOD 300 // Inverses the behavior of leds // #define MY_WITH_LEDS_BLINKING_INVERSE // Enable inclusion mode #define MY_INCLUSION_MODE_FEATURE // Enable Inclusion mode button on gateway #define MY_INCLUSION_BUTTON_FEATURE // Inverses behavior of inclusion button (if using external pullup) //#define MY_INCLUSION_BUTTON_EXTERNAL_PULLUP // Set inclusion mode duration (in seconds) #define MY_INCLUSION_MODE_DURATION 60 // Digital pin used for inclusion mode button #define MY_INCLUSION_MODE_BUTTON_PIN 3 // Uncomment to override default HW configurations //#define MY_DEFAULT_ERR_LED_PIN 4 // Error led pin //#define MY_DEFAULT_RX_LED_PIN 6 // Receive led pin //#define MY_DEFAULT_TX_LED_PIN 5 // the PCB, on board LED // Enable repeater functionality for this node #define MY_REPEATER_FEATURE #include <SPI.h> #include <MySensors.h> #include <Bounce2.h> class Switch { public: uint8_t child_id; int buttonPin; int relayPin; bool relayON; bool relayOFF; Bounce debouncer = Bounce(); Switch(int childId, int button, int relay, int debaunce, bool invertedRelay) { child_id = childId; buttonPin = button; relayPin = relay; relayON = !invertedRelay; relayOFF = invertedRelay; pinMode(buttonPin, INPUT_PULLUP); debouncer.attach(buttonPin); debouncer.interval(debaunce); pinMode(relayPin, OUTPUT); digitalWrite(relayPin, loadState(child_id)?relayON:relayOFF); } MyMessage msg(child_id, V_LIGHT); void Update() { if (debouncer.update()) { // Get the update value. int value = debouncer.read(); // Send in the new value. if(value == LOW) { saveState(child_id, !loadState(child_id)); digitalWrite(relayPin, loadState(child_id)?relayON:relayOFF); send(msg.set(loadState(child_id))); } } } void Present() { present(child_id, S_LIGHT); } void Update(const MyMessage &message) { // We only expect one type of message from controller. But we better check anyway. if (message.type==V_LIGHT && message.sensor==child_id) { // Change relay state digitalWrite(relayPin, message.getBool()?relayON:relayOFF); // Store state in eeprom saveState(message.sensor, message.getBool()); // Write some debug info Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); } } }; void setup() { // Setup locally attached sensors delay(10000); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("Relay", "1.0"); } void loop() { } void receive(const MyMessage &message) { }
PS: if you move the line with: MyMessage msg(child_id, V_LIGHT); at the before class declaration and change the child_id to f.e. 1, everything is compiling....
-
nobody can help? ;-(
-
@gryzli133 said in How can I include MyMessage object in my own class?:
MyMessage msg(child_id, V_LIGHT);
IMO you are trying to initialize MyMessage object before your class has any value for child_id. Can be resolved using object reference.
https://www.embedded.com/electronics-blogs/programming-pointers/4024641/An-Introduction-to-ReferencesSo you wont initialize msg variable until when constructing instance of your class..
Declare MyMessage &msg; in your class
and set value for it in your class constructor: msg = MyMessage(child_id, V_LIGHT);ps. I'm natively writing C# and C++ isnt my strongest language so this might not be right
edit: did read bit more.. you need to init msg before entering inside constructor logic:
class Switch { public: Switch(........ int &child_id ......... ) : msg(child_id, V_LIGHT) { .................. } MyMessage &msg; };
I hope this works
-
@pjr version is almost correct, it would be correct without references, so skip '&' symbol and it should work
-
You are great guys! It compile already, later I will also check the functionality