I'm trying to wrap arduino's RF24 functions into a simpler class that I could use more intuitively in the future, so I have made a .h file:
#ifndef RADIO_H
#define RADIO_H
#include <RF24.h>
#include <Arduino.h>
class Radio
{
private:
RF24 radio(int ce, int csn);
int opMode;
byte address;
protected:
void setReceiver();
void setTransmitter();
public:
Radio(int ce, int csn, int mode, byte channel);
};
#endif
and a .cpp file:
#include "Radio.h"
#include "Parameters.h"
#include <Arduino.h>
#include <SPI.h>
#include <RF24.h>
#include <nRF24L01.h>
Radio::Radio(int ce, int csn, int mode, byte channel){
RF24 radio(ce,csn);
radio.begin();
opMode = mode;
address = channel;
if(opMode == RX){
setReceiver();
}
else if(opMode == TX){
setTransmitter();
}
}
//Protected Functions
void Radio::setReceiver(){
//radio.openReadingPipe(0,address);
//radio.startListening();
}
void Radio::setTransmitter(){
//radio.openWritingPipe(address);
radio.stopListening();
}
However, I'm receiving the following error and can't figure out what's wrong with the code:
sketch\Radio.cpp: In member function 'void Radio::setTransmitter()':
Radio.cpp:74:2: error: invalid use of member function 'RF24
Radio::radio(int, int)' (did you forget the '()' ?)
radio.stopListening(); ^~~~~ Radio.cpp:74:2: error: invalid use of
member function 'RF24 Radio::radio(int, int)' (did you forget the '()'
?) exit status 1 invalid use of member function 'RF24
Radio::radio(int, int)' (did you forget the '()' ?)
can anyone help me figure out what went wrong?
You want an instance of RF24 called radio but you've declared a function called radio that returns an RF24 instance:
class Radio
{
private:
RF24 radio; // remove: (int ce, int csn);
...
Then in your constructor, initialize it like this:
Radio::Radio(int ce, int csn, int mode, byte channel)
: // colon starts the member initializer list
radio(ce, csn) // initialize the radio
{
...
You've declared a member function radio that takes two ints and returns a RF24.
Declare radio as a member variable in the same way as other member variables,
RF24 radio;
and initialize it in the initializer list,
Radio::Radio(int ce, int csn, int mode, byte channel)
: radio(ce, csn)
{
radio.begin();
// ...
Related
I am trying to implement a websocket inside of a class with a library for arduino
(https://github.com/Links2004/arduinoWebSockets/blob/master/src/WebSocketsClient.h) on an esp8266s. I am not using the Arduino IDE but the ESPHome integration of Home-assistant which is why the code has to be inside of a class.
To implement the websocket I have to pass a function to another function but apparently there is a mismatch of data types and I don't understand how to accomplish this. Here is a shortened version of my code:My code:
#include "esphome.h"
#include "WebSocketsClient.h"
#include <iostream>
#include <string.h>
class CustomWebsocket : public Component, public Sensor {
public:
WebSocketsClient webSocket;
CustomWebsocket();
void webSocketEventCustom(WStype_t type, uint8_t * payload, size_t length);
void setup() override;
};
void CustomWebsocket::webSocketEventCustom(WStype_t type, uint8_t * payload, size_t length) {
switch(type) {
case WStype_DISCONNECTED:
break;
case WStype_CONNECTED:
break;
case WStype_TEXT:
//do stuff
break;
};
};
void CustomWebsocket::setup(){
webSocket.begin("192.168.178.23", 81, "/");
webSocket.onEvent(this->webSocketEventCustom);
};
The last line is where the function is passed. It results in this error message:
Error Message:
error: no matching function for call to 'WebSocketsClient::onEvent(<unresolved overloaded function type>)'
webSocket.onEvent(this->webSocketEventCustom);
^
note: candidate is:
In file included from src/CustomWebsocket.h:2:0,
from src/main.cpp:43:
note: void WebSocketsClient::onEvent(WebSocketsClient::WebSocketClientEvent)
void onEvent(WebSocketClientEvent cbEvent);
^
note: no known conversion for argument 1 from '<unresolved overloaded function type>' to 'WebSocketsClient::WebSocketClientEvent {aka std::function<void(WStype_t, unsigned char*, unsigned int)>}'
The data type "WebSocketClientEvent" that is required is specifid in the header file of the library:
Used Library:
class WebSocketsClient : protected WebSockets {
public:
typedef std::function<void(WStype_t type, uint8_t * payload, size_t length)> WebSocketClientEvent;
void onEvent(WebSocketClientEvent cbEvent);
So my question is how do I pass the function in the way required by the library?
I found a solution to my Problem. So apparently there is a difference between normal function and member functions of a class so that pointers to each are also different. A more detailed explanation: https://isocpp.org/wiki/faq/pointers-to-members
I have now set the function and the variables used inside of it static which solves the problem.
I am trying to make functions repository. I have created four files:
Function.hpp, Function.cpp, FunctionsRepository.hpp, FunctionsRepository.cpp
I want to keep pointers to functions in vector of pointers.
//FunctionsRepository.hpp
#ifndef FUNCTIONSREPOSITORY_HPP
#define FUNCTIONSREPOSITORY_HPP
#include <vector>
using namespace std;
class FunctionsRepository {
private:
static vector<double *> pointerToFunctions;
public:
static void addFunction(double * wsk);
};
#endif
//FunctionRepository.cpp
#include "FunctionsRepository.hpp"
void FunctionsRepository::addFunction(double * wsk) {
pointerToFunctions.push_back(wsk);
}
//Functions.hpp
#ifndef FUNCTIONS_HPP
#define FUNCTOINS_HPP
#include "FunctionsRepository.hpp"
int constFunction(int numberOfVehicles);
void linearFunction();
void stepFunction();
#endif
//Funcctions.cpp
#include "Functions.hpp"
double constFunction(double numberOfVehicles){
return numberOfVehicles/2;
}
double (*funcConstant)(double) = constFunction;
//ERROR HERE
FunctionsRepository::addFunction(funcConstant);
I want to add new functions to program as easily as its possible and use it leater in other parts of program.
But I dont get it. Why i am getting this error. The addFunction() method is static, that means I can use it in other classes or parts of program. Vector is static to make sure that is the only one copy for whole program.
Use function wrapper. std::function can stores callable objects. So, your code will contain something like this:
class FunctionsRepository {
private:
// void() - function prototype
static std::vector<std::function<void()>> pointerToFunctions;
public:
static void addFunction(std::function<void()> wsk)
{
pointerToFunctions.push_back(wsk);
}
};
for more information consult official documentation: http://en.cppreference.com/w/cpp/utility/functional/function
I solved It. I received an error because I was calling the FunctionsRepository::addFunction(funcConstant); expression out of any scope. I just created new function to execute this command and thats all.
I am using gdal to do some raster works, well it has a GDALWarpAppOptionsSetProgress function which gets an static function to show its progcess. here you can find its link :Link
and this link
http://gdal.sourcearchive.com/documentation/1.6.0/gdal_8h_5703b651695c0cbe6f3644a0a18dda8b.html
well I know I must write an static function to use it, here is my function
static int My_FN_GDALTermProgress( double dfComplete, const char *pszMessage, void *pData)
{
if(progressBar){
progressBar->setValue(FN_GDAL_PROGRESS_VALUE);
}
double FN_GDAL_PROGRESS_VALUE = dfComplete * 100;
return TRUE;
}
well i have a class named gdal_dem which is like this
#include "gdal_dem.h"
#include "gdal_wrap.h"
#include <qdebug.h>
#include <iostream>
#include "cpl_string.h"
#include "gdal_priv.h"
#include "ogr_spatialref.h"
#include "gdal_utils_priv.h"
#include "cpl_error.h"
#include <QString>
#include "commonutils.h"
#include <QFile>
gdal_dem::gdal_dem(QString SrcFilename):
SrcFile(SrcFilename)
{
}
float FN_GDAL_PROGRESS_VALUE = 0.0f;
static int My_FN_GDALTermProgress(double dfComplete,
CPL_UNUSED const char * pszMessage,
CPL_UNUSED void * pProgressArg )
{
FN_GDAL_PROGRESS_VALUE = dfComplete * 100;
printf("Progress: %f\n",FN_GDAL_PROGRESS_VALUE);
return true;
}
////
int gdal_dem::colorrelief(QString Dstanationfile,QString colorfile){
.....
if(!(psOptionsForBinary->bQuiet))
{
prgFunc=My_FN_GDALTermProgress;
GDALDEMProcessingOptionsSetProgress(psOptions, prgFunc,NULL);
}
......
}
In above code I can set the above mentioned function in processing option and it works fine. but my problem is when I want to update a progress bar. I have a QProgressBar and it is in my main class. How can I pass it into the static function? I tried these ways:
1- I tried to get progressbar in my gdal_dem and also defined a static variable in gdal_dem and tried to set its value and update it in My_FN_GDALTermProgress, the problem is because progressbar is also static I can see it in wrap.cpp's contractor,
2-I tried to define a new My_FN_GDALTermProgress function in my main apps class but it must be static and I faced this error cannot declare member function to have static linkage
3- I also tried this method but it does not work
https://www.badprog.com/c-errors-warnings-cannot-declare-member-function-static-void-myclassmymethod-to-have-static-linkage
Well, How can I pass a parameter to my gdal_dem class and update its value in an static class in it?
Use the pData argument. You can pass anything you want to it when registering the static function. In this case, you can pass a pointer to your QProgressBar object:
QProgressBar* qProgBarObj = // ...
GDALDEMProcessingOptionsSetProgress(psOptions, prgFunc, qProgBarObj);
The static function will then receive it as the third argument:
static int My_FN_GDALTermProgress(double dfComplete, const char *pszMessage, void *pData)
{
auto progBar = reinterpret_cast<QProgressBar*>(pData);
progBar->setValue(/* ... */);
// ...
}
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.
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!
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);
}
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.
I'm trying to make a program involving files assign2.cpp, Player.h, Player.cpp, Team.h, Team.cpp which reads data from a txt file on player info (like hits, atBat, position, name and number) and displays it out into assign2.cpp. assign2.cpp is what contains int main() and is suppose to contain very little code because relies on the other files to do the work.
The error:
request for member getName which is of non-class type ‘char’...
Please help, I've been trying to find the issue and can never do so. The compilation failure :
In file included from Team.cpp:1:0:
Team.h:34:11: warning: extra tokens at end of #endif directive [enabled by default]
Team.cpp: In constructor ‘Team::Team()’:
Team.cpp:15:5: warning: unused variable ‘numPlayers’ [-Wunused-variable]
Team.cpp: In member function ‘void Team::sortByName()’:
Team.cpp:49:56: error: request for member ‘getName’ in ‘((Team*)this
-> Team::playerObject[(j + -1)]’, which is of non-class type ‘char’
Team.cpp:49:74: error: request for member ‘getName’ in ‘bucket’, which is of non-class type ‘int’
Team.cpp: In member function ‘void Team::print()’:
Team.cpp:63:18: error: request for member ‘print’ in ‘((Team*)this)- >Team::playerObject[i]’, which is of non-class type ‘char’
make: *** [Team.o] Error 1
Team.h
#ifndef TEAM_H
#define TEAM_H
#include "Player.h"
class Team
{
private:
char playerObject[40];
int numPlayers; // specifies the number of Player objects
// actually stored in the array
void readPlayerData();
void sortByName();
public:
Team();
Team(char*);
void print();
};
#endif / *Team.h* /
Team.cpp
#include "Team.h"
#include <cstring>
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <string.h>
#include <fstream>
#include <cstdlib>
using namespace std;
Team::Team()
{
strcpy (playerObject,"");
int numPlayers = 0;
}
Team::Team(char* newPlayerObject)
{
strncpy(playerObject, newPlayerObject, 40);
readPlayerData();
}
void Team::readPlayerData()
{
ifstream inFile;
inFile.open("gamestats.txt");
if (!inFile){
cout << "Error, couldn't open file";
exit(1);
}
inFile.read((char*) this, sizeof(Team));
inFile.close();
}
void Team::sortByName()
{
int i, j;
int bucket;
for (i = 1; i < numPlayers; i++)
{
bucket = playerObject[i];
for (j = i; (j > 0) && (strcmp(playerObject[j-1].getName(), bucket.getName()) > 0); j--)
playerObject[j] = playerObject[j-1];
playerObject[j] = bucket;
}
}
Player.h (incase anyone needs it)
#ifndef PLAYER_H
#define PLAYER_H
class Player
{
// Data members and method prototypes for the Player class go here
private:
int number;
char name[26];
char position[3];
int hits;
int atBats;
double battingAverage;
public:
Player();
Player(int, char*, char*, int, int);
char* getName();
char* getPosition();
int getNumber();
int getHits();
int getAtBats();
double getBattingAverage();
void print();
void setAtBats(int);
void setHits(int);
};
#endif
I'm very stuck, Thanks in advance.
In the Team constructor on this line
playerObject = newPlayerObject;
you're trying to assign a value of type char* to a member of type char[40], which doesn't work, since they are two different types. In any case, you probably would need to copy the data from the input instead of just trying to hold the pointer internally. Something like
strncpy(playerObject, newPlayerObject, 40);
Generally, you will always be able to assign a char[N] to a char*, but not the other way around, but that's just because C++ will automatically convert the char[N] to a char*, they are still different types.
Your declaration is:
char playerObject[40];
And your constructor reads:
Team::Team(char* newPlayerObject)
{
playerObject = newPlayerObject;
The error message you referenced in the title of this question obviously comes from here, and it is self explanatory. An array and a pointer are two completely different, incompatible types, when it comes to this kind of an assignment.
What you need to do depends entirely on what you expect to happen, and what your specifications are.
A) You could be trying to initialize the array from the character pointer, in which case you'll probably want to use strcpy(). Of course, you have to make sure that the string, including the null byte terminator, does not exceed 40 bytes, otherwise this will be undefined behavior.
Incidently, this is what you did in your default constructor:
Team::Team()
{
strcpy (playerObject,"");
}
B) Or, your playerObject class member should, perhaps, be a char * instead, and should be either assigned, just like that, or perhaps strdup()ed. In which case your default constructor will probably need to do the same.
Whichever one is the right answer for you depends entirely on your requirements, that you will have to figure out yourself.