New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using PJON in a class example #122

Closed
waspinator opened this Issue Mar 22, 2017 · 12 comments

Comments

Projects
None yet
3 participants
@waspinator

waspinator commented Mar 22, 2017

I'm trying to use PJON in a class, but I'm having troubling calling the set_receiver function. I get an invalid use of non-static member function. It's more of a c++ question, but can you provide an example of how I might do this? Thanks.

#include <PJON.h>

class TestPjon {
  PJON<SoftwareBitBang>* bus;
  int packet;
  public:
    TestPjon(int bus_address);
    void setup_pjon();
    void update_pjon();
    void error_handler(uint8_t code, uint8_t data);
    void receiver_function(uint8_t *payload, uint16_t length, const PJON_Packet_Info &packet_info);
};

TestPjon::TestPjon(int bus_address)
{
  bus = new PJON<SoftwareBitBang>(45);
}

void TestPjon::error_handler(uint8_t code, uint8_t data) {};

void TestPjon::receiver_function(uint8_t *payload, uint16_t length, const PJON_Packet_Info &packet_info) 
{
  if((char)payload[0] == 'B') {
    if(!bus->packets[packet].state)
      packet = bus->reply("B", 1); // Avoid duplicate sending checking old packet state
  }
};

void TestPjon::setup_pjon()
{
  bus->set_receiver(receiver_function);
  bus->strategy.set_pin(12);
  bus->begin();
}

void TestPjon::update_pjon()
{
  bus->receive(50000);
  bus->update();
}


// <Strategy name> bus(selected device id)

TestPjon* test_pjon = new TestPjon(45);

void setup() {
  test_pjon->setup_pjon();
};

void loop() {
  test_pjon->update_pjon();
};
@gioblu

This comment has been minimized.

@gioblu gioblu added the question label Mar 23, 2017

@gioblu

This comment has been minimized.

Owner

gioblu commented Mar 25, 2017

ciao @waspinator is the answer for you satisfactory? Can I close here?
Feel free to ask further support.
Happy tinkering!

@waspinator waspinator closed this Mar 26, 2017

@gingo

This comment has been minimized.

gingo commented Nov 1, 2017

I have exactly the same setup. PJON bus wrapped in class and I need to call set_receiver(class_member_function). AFAIK only static method is allowed :(

Checked linked examples and there is used only PJON_dummy_receiver_handler which is only static method, not a class member.

Thanks in advance!

@gioblu

This comment has been minimized.

Owner

gioblu commented Nov 1, 2017

CIao @gingo. Functions sent by reference must be static. The common way to allow this is to allow a custom pointer to be registered along with the static callback functions, and to pass this pointer to the static callback function at each call. If the callback function is associated with one object of a custom class, the pointer can be used by the receiver function to call functions on that object. It would require a void *custom_ptr parameter to be added to receiver function.

The callback object belonging to a class derived from a callback base class it would be nice and object oriented, but unfortunately pulls in virtual inheritance support that use quite an amount of memory on Arduino.

This approach is used in ModuleInterface.
With this approach, the user must have and register a static callback function, and in this simply call a non-static receiver function for the associated object of his class.

See: https://github.com/fredilarsen/ModuleInterface/blob/bbd73702b84c6d81e1debebdbc8e28c7392d6f3f/src/MI_PJON/PJONModuleInterfaceSet.h

and:
https://github.com/fredilarsen/ModuleInterface/blob/354d16b1be7b17f5278a567b00d72830ccbf024a/src/MI_PJON/PJONModuleInterface.h

If you have in mind a more efficient way to handle this feel free to suggest.
Feel free to close this issue if the answer was satisfactory :)

@gioblu

This comment has been minimized.

Owner

gioblu commented Dec 20, 2017

CIao @gingo and @waspinator thank you for pointing this out. See 3e51c47
Here the use case example: ClassMemberCallback
Now should be possible to do that more easily, this feature will be released along with v10 soon 👍

@gioblu

This comment has been minimized.

Owner

gioblu commented Dec 20, 2017

Will close here, feel free to open back if something is not clear :)

@gioblu gioblu closed this Dec 20, 2017

@gingo

This comment has been minimized.

gingo commented Jan 28, 2018

I just wanna kindly ask you if it would be possible to do the same with error handler method :)

@gioblu

This comment has been minimized.

Owner

gioblu commented Jan 28, 2018

Ciao @waspinator @gingo, sure! I will add the error custom pointer in the next release (10.1) along with the rest. Thank you for pointing out.

@gingo

This comment has been minimized.

gingo commented Feb 9, 2018

@gioblu is this fixed in 10.1? I cannot se a way to read _custom_pointer in error handler.

@gioblu

This comment has been minimized.

Owner

gioblu commented Feb 9, 2018

Ciao @gingo I think I avoided to add this feature in 10.1 because it would break compatibility.
If what you would have is to receive optionally a custom pointer in the error handler, that would change its definition. Is this what you would have available?

Thank you for your support! :)

@gingo

This comment has been minimized.

gingo commented Feb 9, 2018

Yes, I would expect changing error handler signature to:

void error_handler(uint8_t code, uint8_t data, const PJON_Packet_Info &packet_info)

You can overload the setter and allow to use this new handler?

@gingo

This comment has been minimized.

gingo commented Feb 17, 2018

@gioblu is this somehow solved in master? I have to apply weird workarounds again and again because of this ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment