0

I'm using the Arduino IDE and the things network arduino library to create a LoRa mote.

I have created a class which should handle all the LoRa related functions. In this class I need to handle a callback if i receive a downlink message. The ttn library has the onMessage function which I want to setup in my init function and parse another function, which are a class member, called message. I'm getting the error "invalid use of non-static member function".

// File: LoRa.cpp
#include "Arduino.h"
#include "LoRa.h"
#include <TheThingsNetwork.h>

TheThingsNetwork ttn(loraSerial,debugSerial,freqPlan);

LoRa::LoRa(){ 
}

void LoRa::init(){
  // Set the callback
  ttn.onMessage(this->message);
}

// Other functions

void LoRa::message(const uint8_t *payload, size_t size, port_t port)
{
  // Stuff to do when reciving a downlink
}

and the header file

// File: LoRa.h
#ifndef LoRa_h
#define LoRa_h

#include "Arduino.h"
#include <TheThingsNetwork.h>

// Define serial interface for communication with LoRa module
#define loraSerial Serial1
#define debugSerial Serial


// define the frequency plan - EU or US. (TTN_FP_EU868 or TTN_FP_US915)
#define freqPlan TTN_FP_EU868



class LoRa{
  // const vars



  public:
    LoRa();

    void init();

    // other functions

    void message(const uint8_t *payload, size_t size, port_t port);

  private:
    // Private functions
};


#endif

I have tried:

ttn.onMessage(this->message);
ttn.onMessage(LoRa::message);
ttn.onMessage(message);

However none of them worked as I had expected.

Peter Savnik
  • 763
  • 1
  • 8
  • 27
  • 3
    A non-static member function needs an *object* to be called upon. If you don't have an object, you can't use non-static member functions. Once you have an object, I suggest you look into [`std::function`](http://en.cppreference.com/w/cpp/utility/functional/function) and [`std::bind`](http://en.cppreference.com/w/cpp/utility/functional/bind). – Some programmer dude Jun 04 '17 at 14:04

3 Answers3

2

You're trying to call a member function (that means, a function belonging to a member of a class type) without using a class member. That means, what you'd usually do is instantiate a member of your class LoRa first, then call it like:

LoRa loraMember;    
loraMember.message();

Since you're trying to call that function from inside the class itself, without a member of the class calling the init(), you have to make the function static like:

static void message(const uint8_t *payload, size_t size, port_t port);

Then you can use LoRa::message() from anywhere as long as it's public, but calling it just like that will give you another compiler error, since the interface of message asks for "const uint8_t *payload, size_t size, port_t port". So what you'd have to do is call message like:

LoRa::message(payloadPointer, sizeVar, portVar);`

When you call ttn.onMessage(functionCall) what happens is that the function call gets evaluated, then what is returned by that function gets put into the parentheses and ttn.onMessage is called with that. Since your LoRa::message function returns nothing (void) you'll get another error here.

I suggest a good book on C++ basics to get you started - book list

Good luck!

Community
  • 1
  • 1
lavaxp
  • 21
  • 2
0

You should pass arguments to massage as indicated by its prototype:

void message(const uint8_t *payload, size_t size, port_t port);

Since massage returns void, it should not be used as an argument to other functions.

ytobi
  • 535
  • 1
  • 9
  • 19
0

I Solved the problem by making the message function a normal function outside the class. Not sure if it is good practice - but it works.

// File: LoRa.cpp
#include "Arduino.h"
#include "LoRa.h"
#include <TheThingsNetwork.h>

TheThingsNetwork ttn(loraSerial,debugSerial,freqPlan);

void message(const uint8_t *payload, size_t size, port_t port)
{
  // Stuff to do when reciving a downlink
}

LoRa::LoRa(){ 
}

void LoRa::init(){
  // Set the callback
  ttn.onMessage(message);
}
Peter Savnik
  • 763
  • 1
  • 8
  • 27