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-References

    So 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 ;-)


Log in to reply
 

Looks like your connection to MySensors Forum was lost, please wait while we try to reconnect.