How to pass #define value to library



  • Re: How to pass the #define for MySensors

    I found that old topic answering my question, but the answer:
    "The "trick" we use in the mysensors library is to include code files (cpp) in the MySensors.h header file"
    is really not clear to me.
    If I have mylib.h and mylib.cpp, what exactly should I do to have #define values available in library?



  • Maybe more details will interest someone to help and share this "tricky" solution.
    I've written a lightweight code for passive node sending messages to MySensors gateway.
    The goal was to utilize dozens of Attiny's and Atmega's low resources AVR's laying in my drawer for simple motion/door/switch/light/temp remote sensors.
    Code compiles and works stable even on smallest Attinys, the goal was achieved.
    Now I'm trying to create an library based on that code, with "MySensors like" API, to share it.
    For that task the only thing I'm not able to do is to pass #define values from main sketch to the library, which seems to be a standard in MySensors API.
    Whatever i try I always get " NAME was not declared in this scope".
    I've already try to include cpp in header, no progress.
    While I do not understand the "trick", i don't know what I'm doing wrong, and I see it working in MySensors library, so frustrating.
    What do I have to do, to have this example definitions from main code:

    #define MY_NODE_ID 3
    #define MY_CE_PIN 4
    
    #include <MyTinySensors.h>
    
    

    accesible in level of cpp library scope, to use like this?

    
    bool sendRaw( MyMessage* data)
    {
      #if defined MY_CE_PIN
        digitalWrite(MY_CE_PIN, LOW);
        delay(40);
      #endif
    ...
    


  • I think you have to include the source.cpp in the file MyTinySensors.h

    So

    #include "source.cpp"
    


  • Thank you for your response, but still not working 😞
    MyTinySensors.h:

    
    #ifndef MyTinySensors_h
    #define MyTinySensors_h
    #include "MyMessage.h"
    #include "MyTinySensors.cpp"  // ----- source cpp included
    
    bool myTinySensorInit(MyMessage &msg);
    
    bool sendSketchInfo(const char *name, const char *version, MyMessage &msg, const bool requestEcho=false);
    
    bool present(const uint8_t childSensorId, const mysensors_sensor_t sensorType, const char *description, MyMessage &msg, const bool requestEcho =false);
    
    bool send( MyMessage &msg);
    
    bool sendRaw( MyMessage* data);
    
    #endif
    

    begining of MyTinySensors.cpp:

    
    //#include "MyTinySensors.h"  // ------ when not commented, duplicate definition error
    #include "MyMessage.h"
    
    
    bool send( MyMessage &msg)
    {
      msg.setCommand(C_SET);
      return sendRaw(&msg);
    }
    .......
    

    And still:
    ...platformio\lib\MyTinySensors\MyTinySensors.cpp: In function 'bool sendRaw(MyMessage*)':
    ...platformio\lib\MyTinySensors\MyTinySensors.cpp:39:16: error: 'MY_NODE_ID' was not declared in this scope

    Any other ideas what can I try?



  • I've compared your approach to what is done in MySensors.h. In MySensors.h, the cpp file is included instead of the header file.

    #include "core/MyMessage.cpp"
    

    If you follow the same steps like in MySensors.h, it should give the same result.



  • Thank you for your assistance, I think we are close, but not there yet.
    MyMessage is not an issue, it doesn't use global definitions and compiles without errors.
    The "magic" is in MySensorsCore and others libraries, using global definitions.
    In MySensors, include sequence is: Sketch -> include MySensors.h -> include both MysensorsCore.h (line 47) and MysensorsCore.cpp (line 433).
    In my project I try to do (almost) the same: Sketch -> include MyTinySensors.h -> include MyTinySensors.cpp.
    Does not work.
    So let's do exactly same sequence. I've added MyTinyWrapper.h (replacement of MySensors.h), including both MyTinySensors.h and MyTinySensors.cpp, and included MyTinyWrapper.h in main sketch.
    MyTinyWrapper.h:

    #ifndef MyTinyWrapper_h
    #define MyTinyWrapper_h
    
    #include "MyTinySensors.h"
    #include "MyTinySensors.cpp"
    
    #endif
    

    MyTinySensors.h:

    #ifndef MyTinySensors_h
    #define MyTinySensors_h
    #include "MyMessage.h"
    
    bool myTinySensorInit(MyMessage &msg);
    
    bool sendSketchInfo(const char *name, const char *version, MyMessage &msg);
    
    bool present(const uint8_t childSensorId, const mysensors_sensor_t sensorType, const char *description, MyMessage &msg);
    
    bool send( MyMessage &msg);
    
    bool sendRaw( MyMessage* data);
    
    #endif
    

    MyTinySensors.cpp:

    #define SOH 1
    #define STX 2
    #define ETX 3
    #define EOT 4
    #define ICSC_SYS_PACK 0x58
    
    #define GATEWAY_ADDRESS 0
    #define NODE_SENSOR_ID 0xFF
    
    #include "MyTinySensors.h"
    
    bool sendRaw( MyMessage* data)
    {
      #if defined MY_CE_PIN
        digitalWrite(MY_CE_PIN, LOW);
        delay(40);
      #endif
    ....
    

    Result? Still same error 'MY_NODE_ID' was not declared in this scope' in MyTinySensors.cpp
    Can you analyze this if there are any differences with MySensors approach ?



  • @Rbonat said in How to pass #define value to library:

    MY_NODE_ID

    Where have you defined this value exactly?



  • In the begging of main sketch of course 🙂

    #define MY_NODE_ID 3
    #define MY_CE_PIN 4
    
    #define SENSOR_ID 1
    #define sensorPin 2
    
    #include "MyTinyWrapper.h"
    
    
    //attiny13 osc cal
    #include <EEPROM.h>
    bool lastTripped=false;
    MyMessage myMSG;
    
    
    void setup()
    {
      // Attiny13 softserial oscillator callibration
      // Check if there exist any OSCCAL value in EEPROM addr. 0
      // If not, run the oscillator tuner sketch first
      uint8_t cal = EEPROM.read(0);
      if(cal < 0x7F)
      OSCCAL = cal;
    
      //Init MyTinySensors library and presentation of node and sensors
      myTinySensorInit(myMSG);
      sendSketchInfo("Test3", "2.1", myMSG);
      present(SENSOR_ID, S_MOTION, "My Motion", myMSG);
      
      //send initial values - mandatory for Home Assistant integration
      myMSG.setSensor(SENSOR_ID);
      myMSG.setType(V_TRIPPED);
      myMSG.set(false);
      send(myMSG);
      pinMode(sensorPin, INPUT_PULLUP);      // sets the motion sensor digital pin as input
    }
    
    void loop()
    {
     bool tripped = digitalRead(sensorPin);
     if (tripped != lastTripped)
     {
       myMSG.set(tripped);
       send(myMSG);
       lastTripped=tripped;
     }
    }
    
    


  • The only difference I see, is that MY_NODE_ID is not used in MysensorsCore, but only in MyTransport.
    It looks like you are close indeed, but I don't get this neither.
    I hope someone else can help and let us know if you succeeded...



  • I think I understand what is happening.
    The compiler compiles all source files it finds in the folder. So when compiling the sketch itself everything goes fine I think. When the compiler comes across the MyTinySensors.cpp, it tries to compile that file also but can't find the define MY_NODE_ID.
    So I think you should move these files to subfolders (like done in the MySensors structure), so they won't be compiled individually anymore. Sounds plausible right?


Log in to reply
 

Suggested Topics

  • 4
  • 1
  • 10
  • 54
  • 186
  • 10
  • 4
  • 5

66
Online

10.5k
Users

10.8k
Topics

110.6k
Posts