Error : request for member 'set' in 'Phase1_Voltage', which is of non-class type 'float'



  • I am building a MySensors serial <->RS485 node, which also has to read out a modbus enable energy monitoring device (Schneider PM9C).
    The modbus part is working great, so now i am trying to send the measured values as MySensors data so i can pick them up with Domoticz.

    My code at the moment :

    #define MY_GATEWAY_SERIAL               // Enable serial gateway mode
    #define MY_RS485                         // Enable RS485 transport layer
    #define MY_RS485_HWSERIAL Serial2       // Set serial interface to use for RS-485
    #define MY_RS485_BAUD_RATE 9600         // Set RS485 baud rate to use
    #define MY_RS485_DE_PIN 2               // Define this to enables DE-pin management on defined pin
    
    #include <MySensors.h>
    #include <ModbusMaster.h>
    
    #define CHILD_ID_Phase1_Current         11
    #define CHILD_ID_Phase2_Current         12
    #define CHILD_ID_Phase3_Current         13
    #define CHILD_ID_Neutral_Current        14
    #define CHILD_ID_Phase12_Voltage        21
    #define CHILD_ID_Phase23_Voltage        22
    #define CHILD_ID_Phase31_Voltage        23
    #define CHILD_ID_Phase1_Voltage         24
    #define CHILD_ID_Phase2_Voltage         25
    #define CHILD_ID_Phase3_Voltage         26
    #define CHILD_ID_Frequency              30
    #define CHILD_ID_Total_Active_Power     41
    #define CHILD_ID_Total_Reactive_Power   42
    #define CHILD_ID_Total_Apparant_Power   43
    #define CHILD_ID_Total_Power_Factor     44
    #define CHILD_ID_Power_Factor_Sector    45
    #define CHILD_ID_Power_Demand           50
    #define CHILD_ID_Max_Power_Demand       51
    #define CHILD_ID_Phase1_Active_Power    60
    #define CHILD_ID_Phase1_Reactive_Power  61
    #define CHILD_ID_Phase2_Active_Power    62
    #define CHILD_ID_Phase2_Reactive_Power  63
    #define CHILD_ID_Phase3_Active_Power    64
    #define CHILD_ID_Phase3_Reactive_Power  65
    
    ModbusMaster node;                         // Initiate ModbusMaster object
    
    MyMessage Phase1_Current        (CHILD_ID_Phase1_Current,V_CURRENT);
    MyMessage Phase2_Current        (CHILD_ID_Phase2_Current, V_CURRENT);
    MyMessage Phase3_Current        (CHILD_ID_Phase3_Current, V_CURRENT);
    MyMessage Neutral_Current       (CHILD_ID_Neutral_Current, V_CURRENT);
    MyMessage Phase12_Voltage       (CHILD_ID_Phase12_Voltage, V_VOLTAGE);
    MyMessage Phase23_Voltage       (CHILD_ID_Phase23_Voltage, V_VOLTAGE);
    MyMessage Phase31_Voltage       (CHILD_ID_Phase31_Voltage, V_VOLTAGE);
    MyMessage Phase1_Voltage        (CHILD_ID_Phase1_Voltage, V_VOLTAGE);
    MyMessage Phase2_Voltage        (CHILD_ID_Phase2_Voltage, V_VOLTAGE);
    MyMessage Phase3_Voltage        (CHILD_ID_Phase3_Voltage, V_VOLTAGE);
    MyMessage Total_Active_Power    (CHILD_ID_Total_Active_Power, V_WATT);
    MyMessage Total_Reactive_Power  (CHILD_ID_Total_Reactive_Power, V_VAR);
    MyMessage Total_Apparant_Power  (CHILD_ID_Total_Apparant_Power, V_VA);
    MyMessage Total_Power_Factor    (CHILD_ID_Total_Power_Factor, V_POWER_FACTOR);
    MyMessage Phase1_Active_Power   (CHILD_ID_Phase1_Reactive_Power, V_WATT);
    MyMessage Phase1_Reactive_Power (CHILD_ID_Phase1_Reactive_Power, V_VAR);
    MyMessage Phase2_Active_Power   (CHILD_ID_Phase1_Reactive_Power, V_WATT);
    MyMessage Phase2_Reactive_Power (CHILD_ID_Phase1_Reactive_Power, V_VAR);
    MyMessage Phase3_Active_Power   (CHILD_ID_Phase1_Reactive_Power, V_WATT);
    MyMessage Phase3_Reactive_Power (CHILD_ID_Phase1_Reactive_Power, V_VAR);
    
    // Functions to restore measured values after modbus tranfer (The PM9C sends it's 32-bit signed and unsigned measurements as 2 16-bit words, the divider is to scale to the corrent unit)
    
    float UnsignedValue (int reg, int divider) {
      unsigned long msb = node.getResponseBuffer(reg);
      msb = msb << 16;
      unsigned int  lsb = node.getResponseBuffer(reg + 1);
      unsigned long total = msb | lsb;
      float result = float (total) / divider;
      return result;
    }
    
    float SignedValue (int reg, int divider) {
      signed long msb = node.getResponseBuffer(reg);
      msb = msb << 16;
      unsigned int  lsb = node.getResponseBuffer(reg + 1);
      signed long total = msb | lsb;
      float result = float (total) / divider;
      return result;
    }
    
    
    void setup()
    {
      Serial3.begin (19200, SERIAL_8N1);       // Use Serial 3 for Modbus RTU @ 19200 8N1 using Moxa RS232<->RS485 converter (Auto direction control)
      node.begin(1, Serial3);                  // Communicate with Modbus slave ID 1
    }
    
    
    void presentation()
    {
      sendSketchInfo("RS485 gateway with Modbus", "0.1");
    
      present(CHILD_ID_Phase1_Current, S_MULTIMETER);
      present(CHILD_ID_Phase2_Current, S_MULTIMETER);
      present(CHILD_ID_Phase3_Current, S_MULTIMETER);
      present(CHILD_ID_Neutral_Current, S_MULTIMETER);
      present(CHILD_ID_Phase12_Voltage, S_MULTIMETER);
      present(CHILD_ID_Phase23_Voltage, S_MULTIMETER);
      present(CHILD_ID_Phase31_Voltage, S_MULTIMETER);
      present(CHILD_ID_Phase1_Voltage, S_MULTIMETER);
      present(CHILD_ID_Phase2_Voltage, S_MULTIMETER);
      present(CHILD_ID_Phase3_Voltage, S_MULTIMETER);
      present(CHILD_ID_Total_Active_Power, S_POWER);
      present(CHILD_ID_Total_Reactive_Power, S_POWER);
      present(CHILD_ID_Total_Apparant_Power, S_POWER);
      present(CHILD_ID_Total_Power_Factor, S_POWER);
      present(CHILD_ID_Phase1_Active_Power, S_POWER);
      present(CHILD_ID_Phase1_Reactive_Power, S_POWER);
      present(CHILD_ID_Phase2_Active_Power, S_POWER);
      present(CHILD_ID_Phase2_Reactive_Power, S_POWER);
      present(CHILD_ID_Phase3_Active_Power, S_POWER);
      present(CHILD_ID_Phase3_Reactive_Power, S_POWER);
    }
    
    void loop()
    {
        node.readHoldingRegisters(0x3E8, 56);
    
        float Phase1_Current        = UnsignedValue (0, 1000);
        float Phase2_Current        = UnsignedValue (2, 1000);
        float Phase3_Current        = UnsignedValue (4, 1000);
        float Neutral_Current       = UnsignedValue (6, 1000);
        float Phase12_Voltage       = UnsignedValue (8, 1000);
        float Phase23_Voltage       = UnsignedValue (10, 1000);
        float Phase31_Voltage       = UnsignedValue (12, 1000);
        float Phase1_Voltage        = UnsignedValue (14, 1000);
        float Phase2_Voltage        = UnsignedValue (16, 1000);
        float Phase3_Voltage        = UnsignedValue (18, 1000);
        float Total_Active_Power    = UnsignedValue (22, 100);
        float Total_Reactive_Power  =   SignedValue (24, 100);
        float Total_Apparant_Power  = UnsignedValue (26, 100);
        float Total_Power_Factor    =   SignedValue (28, 100);
        float Phase1_Active_Power   =   SignedValue (44, 100);
        float Phase2_Active_Power   =   SignedValue (46, 100);
        float Phase3_Active_Power   =   SignedValue (48, 100);
        float Phase1_Reactive_Power =   SignedValue (50, 100);
        float Phase2_Reactive_Power =   SignedValue (52, 100);
        float Phase3_Reactive_Power =   SignedValue (54, 100);
      
        send(Phase1_Current.set(Phase1_Current));
        send(Phase2_Current.set(Phase1_Current));
        send(Phase3_Current.set(Phase1_Current));
        send(Neutral_Current.set(Phase1_Current));
        send(Phase1_Voltage.set(Phase1_Voltage));
        send(Phase2_Voltage.set(Phase1_Voltage));
        send(Phase3_Voltage.set(Phase1_Voltage));
        send(Total_Active_Power.set(Total_Active_Power));
    }
    
    

    I am only trying to send out a small subset of the available data, and i have not set up things like timing etc for the measurements yet, but i am stuck at the "send" part. The values created by the PM9C come in through modbus as 2 16-bit words. These are combined into 32-bit signed or unsigned longs which give the measured values, then converted to a float to be divided by a scaling factor to correct the measurements unit. The currents are given in mA, voltages in mV etc. These are brought back to A, V, kW etc.

    So my measurements are all float values. (some signed, most of them unsigned)

    Since the S_POWER type does not include voltage, currents etc, i have divided my data over both S_POWER and S_MULTIMETER types.
    But this won't fly.. If i compile the code to check for errors, it produces numerous issues :

    Arduino: 1.8.0 (Windows 10), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"
    
    Gateway-RS485andModBus.ino: In function 'void loop()':
    
    Gateway-RS485andModBus:157: error: request for member 'set' in 'Phase1_Current', which is of non-class type 'float'
       send(Phase1_Current.set(Phase1_Current));
                           ^
    
    Gateway-RS485andModBus:158: error: request for member 'set' in 'Phase2_Current', which is of non-class type 'float'
       send(Phase2_Current.set(Phase1_Current));
                           ^
    
    Gateway-RS485andModBus:159: error: request for member 'set' in 'Phase3_Current', which is of non-class type 'float'
       send(Phase3_Current.set(Phase1_Current));
                           ^
    
    Gateway-RS485andModBus:160: error: request for member 'set' in 'Neutral_Current', which is of non-class type 'float'
       send(Neutral_Current.set(Phase1_Current));
                            ^
    
    Gateway-RS485andModBus:161: error: request for member 'set' in 'Phase12_Voltage', which is of non-class type 'float'
       send(Phase12_Voltage.set(Phase12_Voltage));
                            ^
    
    Gateway-RS485andModBus:162: error: request for member 'set' in 'Phase23_Voltage', which is of non-class type 'float'
       send(Phase23_Voltage.set(Phase23_Voltage));
                            ^
    
    Gateway-RS485andModBus:163: error: request for member 'set' in 'Phase31_Voltage', which is of non-class type 'float'
       send(Phase31_Voltage.set(Phase31_Voltage));
                            ^
    
    Gateway-RS485andModBus:164: error: request for member 'set' in 'Phase1_Voltage', which is of non-class type 'float'
       send(Phase1_Voltage.set(Phase1_Voltage));
                           ^
    
    Gateway-RS485andModBus:165: error: request for member 'set' in 'Phase2_Voltage', which is of non-class type 'float'
       send(Phase2_Voltage.set(Phase1_Voltage));
                           ^
    
    Gateway-RS485andModBus:166: error: request for member 'set' in 'Phase3_Voltage', which is of non-class type 'float'
       send(Phase3_Voltage.set(Phase1_Voltage));
                           ^
    
    Gateway-RS485andModBus:167: error: request for member 'set' in 'Total_Active_Power', which is of non-class type 'float'
       send(Total_Active_Power.set(Total_Active_Power));
                               ^
    

    What am i doing wrong here ? Is the mysensors lib unable to handle floats as data ? did i forget something ? made a major f<censored>up ?


  • Mod

    @Redguy Phase1_Current is a float inside your function. You cannot call set() method on a float as it doesn't exist.
    I guess you want to call set on a message variable, which you named the same in global context. Rename the messages (or the floats) to fix things.



  • Thanks Yveaux,

    This led to a whole new range over errors : call of overloaded 'set(float)' is ambiguous

    I resolved the issue by changing the send command from :

     send(Phase1_Current.set(m_Phase1_Current));
    

    to

      send(Phase2_Current.set((float)m_Phase2_Current,1));
    

    Which is working fine now.


Log in to reply
 

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