Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 7 of 7

Thread: Help writing a library (passing in an unknown structure for serial writing)

  1. #1
    Senior Member
    Join Date
    Apr 2017
    Posts
    189

    Help writing a library (passing in an unknown structure for serial writing)

    All,

    I've been using small UART based transcievers (E50-TTL-100) with great success. I can read / write and even program them. RadioHead library will work with and E32, but I want different functions and capability--hence I'm writing my own.

    The Transceiver serial is created with something like
    #define ESerial Serial1

    initialization is then
    ESerial.begin(9600);

    I send complete data structures (Data.volts, Data.amps, Data.ID, etc..) and this code works fine
    ESerial.write((uint8_t*) &Data, sizeof(Data));

    My library creates an object using (which is library code leveraged from RadioHead)
    EBYTE Transceiver(&ESerial, 4, 5, 6);

    library constructor is
    EBYTE::EBYTE(Stream *s, uint8_t PIN_M0, uint8_t PIN_M1, uint8_t PIN_AUX)

    OK...enough background. In the library I'm writing I want a function like the following so i can pass a data structure but as I wan't to let others have the lib, how do you pass a structure when you don't know anything about it?

    void EBYTE::SendTheData( ? *TheStructure) {
    _s->write((uint8_t*)&TheStructure, (uint16_t) sizeof(TheStructure));
    }

    Thanks in advance.

  2. #2
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,310
    You probably want to look into C++ templates:


    Alternatively, you could do it the C way, and instead have a macro that does the call:
    Code:
    #define DO_CALL(ST) EBYTE::SendTheData ((uint8_t *)&(ST), (uint16_t) sizeof (ST))
    
    // ...
    
      struct foo bar;
      DO_CALL (bar)

  3. #3
    Just change your function signature to:
    Code:
    void EBYTE::SendData(const void *data_, unsigned size_)
    {
      s_->write(data_, size_);
    }

  4. #4
    Senior Member
    Join Date
    Apr 2017
    Posts
    189
    Thanks Jarkkol, I implemented and got the code to compile, but it doesn't work. I can pass in a data structure but the reported sizeof is 2 bytes. I'm told that the size of “void *” is the size of a pointer to memory (2 bytes on this operating system/compiler).

    I'm still looking for a way to pass a structure into my function but not requiring the name of the structure. Since this lib can be used by anyone structure names will be different.

    MichaelMeissner. I may have to implement your idea but I'm hoping to keep the end user code nice and pretty like: EBYTE.init(); EBYTE.setChannel(); EBYTE.SendData().

  5. #5
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    537
    That's why you need the size as a function parameter as well. Consider memcpy, which is:
    Code:
    memcpy(void *dest, void *src, size_t size)
    In your case, JarkkoL recommended:
    Code:
    void EBYTE::SendData(const void *data_, unsigned size_)
    {
      s_->write(data_, size_);
    }
    You need to use the size input parameter instead of sizeof.

  6. #6
    Senior Member
    Join Date
    Apr 2017
    Posts
    189
    All,

    I could really use some more complete help here, a line of code may help an experienced c programmer but it's making me more confused. I'm not a c programmer and have no idea how to implement memcopy. maybe just correct my code below?

    My code in the .ion file
    // structure created above
    // object to Transceiver created above
    Transceiver.GetTheData(&TheData, sizeof(TheData));


    prototype in .h

    void SendTheData(const void *TheStructure, uint16_t *size_);


    code in the cpp file

    void EBYTE::SendTheData(const void *TheStructure, uint16_t *size_) {

    _s->write((uint8_t *) TheStructure, uint16_t size_);


    }

  7. #7
    Senior Member
    Join Date
    Apr 2017
    Posts
    189
    looks like i got it working

    ino file
    Transceiver.GetTheData(&TheData, sizeof(TheData));


    .h file
    void GetTheData(const void *TheStructure, uint16_t size_);

    .cpp file
    void EBYTE::GetTheData(const void *TheStructure, uint16_t size_) {

    _s->readBytes((uint8_t *) TheStructure, size_);


    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •