ESP32: Compile errors when using IRAM_ATTR - c++

I am sure I am doing something really stupid, but here goes..
I get a compile error when I use IRAM_ATTR for my ISR. I am compiling for ESP32.
Here is the definition of the ISR
void
IRAM_ATTR
detectsBlockOccupancy() {
....
ISR code..
...
}
And here is the first usage:
void setup() {
// Set Sensor pin as interrupt, assign interrupt function and set RISING mode
attachInterrupt(digitalPinToInterrupt(BDInterruptPin), detectsBlockOccupancy, RISING);
...
}
The error I get is as follows:
In function 'void setup()': Node0:226:90: error: invalid conversion
from 'int ()()' to 'void ()()' [-fpermissive]
attachInterrupt(digitalPinToInterrupt(BDInterruptPin), detectsBlockOccupancy, RISING);
^ In file included from
C:\Users\vibhas\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\cores\esp32/esp32-hal.h:53:0,
from C:\Users\vibhas\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\cores\esp32/Arduino.h:35,
from sketch\Node0.ino.cpp:1: C:\Users\vibhas\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\cores\esp32/esp32-hal-gpio.h:81:6:
note: initializing argument 2 of 'void attachInterrupt(uint8_t, void
()(), int)' void attachInterrupt(uint8_t pin, void ()(void), int
mode);
^
If I remove the IRAM_ATTR then it compiles fine. It seems to think that I am trying to pass a different type of function pointer.
What could I be doing wrong ?
Thanks
vibhas

Related

callback in MCS6502 functions will not compile in arduino on esp32 but will compile in codeblocks c file

I know this is a noob question bit I am not familiar with c++ .
My understanding is that arduino code compiles in c++ and this is what causes the problem in compiling.
The code below will compile fine in codeblocks and will run correctly , however if I use the same code without any modifications then it will produce an error at compile time.
heres is the .ino file
#include "MCS6502.h"
int8_t ram [65535];
//////CALL BACK FUNCTION ///////////////////////////////////////////////
uint8_t readBytesFunction(uint16_t add) {
uint8_t tc = 5;
tc = ram[add];
return tc;
}
//////CALL BACK FUNCTION ///////////////////////////////////////////////
void writeBytesFunction(uint16_t add,uint8_t bb) {
}
void setup()
{
Serial.begin(115200);
Serial.println();
///CODE BELOW WILL COMPILE AND RUN IN CODEBLOCKS BUT WILL NOT COMPILE IN ARDUINO
/////////////////////////////////////////////////////////////////////
MCS6502ExecutionContext context;
MCS6502Init(&context, readBytesFunction, writeBytesFunction, NULL); // Final param is optional conte>
MCS6502Reset(&context);
MCS6502Tick(&context); //use timings
MCS6502ExecNext(&context); //as fast as possible
}
these are the errors after compiling in arduino for esp32
MCS6502.ino: In function 'void setup()':
wahid_MCS6502:22:27: error: invalid conversion from 'uint8_t (*)(uint16_t)' {aka 'unsigned char (*)(short unsigned int)'} to 'MCS6502DataReadByteFunction' {aka 'unsigned char (*)(short unsigned int, void*)'} [-fpermissive]
MCS6502Init(&context, readBytesFunction, writeBytesFunction, NULL); // Final param is optional conte>
^~~~~~~~~~~~~~~~~
MCS6502.h:91:33: note: initializing argument 2 of 'void MCS6502Init(MCS6502ExecutionContext*, MCS6502DataReadByteFunction, MCS6502DataWriteByteFunction, void*)'
MCS6502DataReadByteFunction readByteFn,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~
MCS6502:22:46: error: invalid conversion from 'void (*)(uint16_t, uint8_t)' {aka 'void (*)(short unsigned int, unsigned char)'} to 'MCS6502DataWriteByteFunction' {aka 'void (*)(short unsigned int, unsigned char, void*)'} [-fpermissive]
MCS6502Init(&context, readBytesFunction, writeBytesFunction, NULL); // Final param is optional conte>
^~~~~~~~~~~~~~~~~~
MCS6502.h:92:34: note: initializing argument 3 of 'void MCS6502Init(MCS6502ExecutionContext*, MCS6502DataReadByteFunction, MCS6502DataWriteByteFunction, void*)'
MCS6502DataWriteByteFunction writeByteFn,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~
exit status 1
invalid conversion from 'uint8_t (*)(uint16_t)' {aka 'unsigned char (*)(short unsigned int)'} to 'MCS6502DataReadByteFunction' {aka 'unsigned char (*)(short unsigned int, void*)'} [-fpermissive]
what do i need to do it compiles in arduino ??
apologies if some details are missing from this question but its my 1st ever time asking a question here.
many thanks
I'm guessing that you are using this library?
Looking at the signatures of the callback functions both require a final void* parameter which your callbacks are missing.
You need:
uint8_t readBytesFunction(uint16_t add, void*) {
uint8_t tc = 5;
tc = ram[add];
return tc;
}
void writeBytesFunction(uint16_t add,uint8_t bb, void*) {
}

Linux - signal: error: invalid use of non-static member function

I originally wrote some tests to test the functionality of signals for my program. The tests proved promising, however moving the small code changes to my class in my source code has given me a few problems.
I have added two functions: setAlarm(), and a callback alarm_handler. setAlarm() does as it says, which is set the alarm. Once time expires, alarm handler is called which runs an execute function.
a.cpp
int Database::alarm_handler(int signum)
{
dbExecSql();
}
void Database::setAlarm()
{
signal(SIGALRM, alarm_handler);
ualarm(500000,0);
}
b.h
class Database
{
public:
int alarm_handler(int signum);
void setAlarm();
dbExecSql();
};
error
error: invalid use of non-static member function
signal(SIGALRM, alarm_handler);
Any help would be appreciated.
EDIT
I have modified alarm_handler to be removed from my class, however am now am receiving:
error: invalid conversion from β€˜int (*)(int)’ to β€˜__sighandler_t {aka void (*)(int)}’ [-fpermissive]
signal(SIGALRM, alarm_handler);
^
The signal handler function (alarm_handler) can't be member function and should be a standalone function with C linkage.
Remove it from your class:
void alarm_handler(int signum)
{
dbExecSql();
}
Beware that only async-signal-safe functions can be called from signal handlers safely. So you need to ensure dbExecSql() respects that.

unexpected error message, arduino SharpIR

I am trying to use a GPY2Y0A21Y IRsensor, but I am having trouble making the code work. I downloaded SharpIR but got a bug when using one of its functions,
#include <SharpIR.h>
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
SharpIR sharp("A1", 25, 93, 1080);
}
void loop() {
// put your main code here, to run repeatedly:
}
and this is the error message
/var/folders/_z/t_qth0vd0xj6fxvyp_k5nvc00000gn/T/arduino_modified_sketch_475607/sketch_jan17a.ino: In function 'void setup()':
sketch_jan17a:7: error: no matching function for call to 'SharpIR::SharpIR(const char [3], int, int, int)'
SharpIR sharp("A1", 25, 93, 1080);
^
/var/folders/_z/t_qth0vd0xj6fxvyp_k5nvc00000gn/T/arduino_modified_sketch_475607/sketch_jan17a.ino:7:33: note: candidates are:
In file included from /var/folders/_z/t_qth0vd0xj6fxvyp_k5nvc00000gn/T/arduino_modified_sketch_475607/sketch_jan17a.ino:1:0:
/Users/jeroenturkstra/Documents/Arduino/libraries/SharpIR/src/SharpIR.h:29:5: note: SharpIR::SharpIR(uint8_t, uint8_t)
SharpIR(uint8_t _sensorType, uint8_t _sensorPin);
^
/Users/jeroenturkstra/Documents/Arduino/libraries/SharpIR/src/SharpIR.h:29:5: note: candidate expects 2 arguments, 4 provided
/Users/jeroenturkstra/Documents/Arduino/libraries/SharpIR/src/SharpIR.h:25:7: note: constexpr SharpIR::SharpIR(const SharpIR&)
class SharpIR
^
/Users/jeroenturkstra/Documents/Arduino/libraries/SharpIR/src/SharpIR.h:25:7: note: candidate expects 1 argument, 4 provided
/Users/jeroenturkstra/Documents/Arduino/libraries/SharpIR/src/SharpIR.h:25:7: note: constexpr SharpIR::SharpIR(SharpIR&&)
/Users/jeroenturkstra/Documents/Arduino/libraries/SharpIR/src/SharpIR.h:25:7: note: candidate expects 1 argument, 4 provided
exit status 1
no matching function for call to 'SharpIR::SharpIR(const char [3], int, int, int)'
I am not super familiar with libraries and such so I have no clue what is wrong with this code. All I got is that the function doesn't exist. I did download SharpIR btw. If anyone can help, it would be appreciated (had the example code from this site https://playground.arduino.cc/Main/SharpIR)
The error seems to be legit, looking at the SharpIR declaration. Maybe the guide that you are following is deprecated and not compatible with your installed library?
class SharpIR
{
public:
SharpIR (int irPin, long sensorModel);
int distance();
private:
void sort(int a[], int size);
int _irPin;
long _model;
};
The object initialization requires only a pin number and a long that identifies the sensor model. BUT looking at the error in your question it seems that the declarations is implemented with the sensor identification number as first argument and the pin number as second. I think you should really open up the source in your local installation and check it out. You can print it in terminal with:
cat /Users/jeroenturkstra/Documents/Arduino/libraries/SharpIR/src/SharpIR.h
(I cannot open Dropbox link right now...)

Compilation error Arduino C++ object library

I'm writing a C++ Arduino library for BlueTooth communication.
I implemented a mechanism in order to register a custom function to be executed when a certain byte comes from the BT connection. Pratically a sort of Java Hashmap.
Everything works fine but when I try to register a method of the library object in the constructor I got some compilation error which I cannot understand.
I'm using Arduino IDE 1.6.9 with Ubuntu 16.04 LTS 64bit. The board is an Arduino UNO.
Here below the code,
header:
#ifndef BlueHartwin_H
#define BlueHartwin_H
#include <SoftwareSerial.h>
#include <Streaming.h>;
#include <Arduino.h>
#define START_TX 254
#define STOP_TX 255
typedef void (* CmdFuncPtr) (); // this is a typedef to command functions
class BlueHartwin {
public:
BlueHartwin(byte bluetoothTx,byte bluetoothRx,long baudRate);
~BlueHartwin();
boolean registerCmd(byte id,CmdFuncPtr cmdFuncPtr);
boolean unRegisterCmd(byte id,CmdFuncPtr cmdFuncPtr);
boolean runCmd(byte id);
void setDataLength(byte dataLength);
byte getDataLength();
byte getIncomingByte();
void txSwitchOff(void);
void txSwitchOn(void);
bool isTx();
boolean available();
boolean read();
void write(byte data,boolean endLine);
private:
CmdFuncPtr setOfCmds[255];
byte mDataLength;
bool tx;
byte incomingByte;
};
#endif
body:
#include "BlueHartwin.h";
/*
* Reserved command IDs:
* 14,
* 15
*/
SoftwareSerial bluetooth(7,8);
BlueHartwin::BlueHartwin(byte bluetoothTx,byte bluetoothRx,long baudRate){
bluetooth = SoftwareSerial(bluetoothTx,bluetoothRx);
bluetooth.begin(baudRate);
for (int i=0;i<=255;i++) {
setOfCmds[i]=NULL;
}
tx=false;
registerCmd(14,&txSwitchOff);
registerCmd(15,&txSwitchOn);
}
BlueHartwin::~BlueHartwin(){
}
boolean BlueHartwin::registerCmd(byte id,CmdFuncPtr cmdFuncPtr){
if (setOfCmds[id]==NULL) {
setOfCmds[id]=cmdFuncPtr;
return true;
} else return false;
}
boolean BlueHartwin::unRegisterCmd(byte id,CmdFuncPtr cmdFuncPtr){
setOfCmds[id]=NULL;
return true;
}
boolean BlueHartwin::runCmd(byte id){
if (setOfCmds[id]!=NULL) {
setOfCmds[id]();
return true;
} else return false;
}
void BlueHartwin::setDataLength(byte dataLength) {
mDataLength=dataLength;
}
byte BlueHartwin::getDataLength(){
return mDataLength;
}
byte BlueHartwin::getIncomingByte(){
return incomingByte;
}
boolean BlueHartwin::isTx(){
return tx;
}
void BlueHartwin::txSwitchOff(void){
tx=false;
Serial<<"now tx is "<<tx<<endl;
}
void BlueHartwin::txSwitchOn(void){
tx=true;
Serial<<"now tx is "<<tx<<endl;
}
boolean BlueHartwin::available(){
return bluetooth.available();
}
boolean BlueHartwin::read(){
if (bluetooth.available()>0)
{
incomingByte=bluetooth.read();
Serial << "Incoming byte " << incomingByte<<endl;
return runCmd(incomingByte);
}
return false;
}
void BlueHartwin::write(byte data,boolean endLine){
if (tx) {
if (endLine) bluetooth << data << endl;
else bluetooth<<data;
}
}
error:
/home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.cpp: In constructor 'BlueHartwin::BlueHartwin(byte, byte, long int)':
/home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.cpp:21:18: error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say '&BlueHartwin::txSwitchOff' [-fpermissive]
registerCmd(14,&txSwitchOff);
^
/home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.cpp:21:29: error: no matching function for call to 'BlueHartwin::registerCmd(int, void (BlueHartwin::*)())'
registerCmd(14,&txSwitchOff);
^
/home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.cpp:21:29: note: candidate is:
In file included from /home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.cpp:1:0:
/home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.h:19:10: note: boolean BlueHartwin::registerCmd(byte, CmdFuncPtr)
boolean registerCmd(byte id,CmdFuncPtr cmdFuncPtr);
^
/home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.h:19:10: note: no known conversion for argument 2 from 'void (BlueHartwin::*)()' to 'CmdFuncPtr {aka void (*)()}'
/home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.cpp:22:18: error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say '&BlueHartwin::txSwitchOn' [-fpermissive]
registerCmd(15,&txSwitchOn);
^
/home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.cpp:22:28: error: no matching function for call to 'BlueHartwin::registerCmd(int, void (BlueHartwin::*)())'
registerCmd(15,&txSwitchOn);
^
/home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.cpp:22:28: note: candidate is:
In file included from /home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.cpp:1:0:
/home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.h:19:10: note: boolean BlueHartwin::registerCmd(byte, CmdFuncPtr)
boolean registerCmd(byte id,CmdFuncPtr cmdFuncPtr);
^
/home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.h:19:10: note: no known conversion for argument 2 from 'void (BlueHartwin::*)()' to 'CmdFuncPtr {aka void (*)()}'
exit status 1
Errore durante la compilazione per la scheda Arduino/Genuino Uno.
If I change in the constructor the rows:
registerCmd(14,&txSwitchOff);
registerCmd(15,&txSwitchOn);
to
registerCmd(14,&BlueHartwin::txSwitchOff);
registerCmd(15,&BlueHartwin::txSwitchOn);
I got this error:
/home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.cpp: In constructor 'BlueHartwin::BlueHartwin(byte, byte, long int)':
/home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.cpp:21:42: error: no matching function for call to 'BlueHartwin::registerCmd(int, void (BlueHartwin::*)())'
registerCmd(14,&BlueHartwin::txSwitchOff);
^
/home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.cpp:21:42: note: candidate is:
In file included from /home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.cpp:1:0:
/home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.h:19:10: note: boolean BlueHartwin::registerCmd(byte, CmdFuncPtr)
boolean registerCmd(byte id,CmdFuncPtr cmdFuncPtr);
^
/home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.h:19:10: note: no known conversion for argument 2 from 'void (BlueHartwin::*)()' to 'CmdFuncPtr {aka void (*)()}'
/home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.cpp:22:41: error: no matching function for call to 'BlueHartwin::registerCmd(int, void (BlueHartwin::*)())'
registerCmd(15,&BlueHartwin::txSwitchOn);
^
/home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.cpp:22:41: note: candidate is:
In file included from /home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.cpp:1:0:
/home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.h:19:10: note: boolean BlueHartwin::registerCmd(byte, CmdFuncPtr)
boolean registerCmd(byte id,CmdFuncPtr cmdFuncPtr);
^
/home/paolo/ARDUINO/arduino-1.6.9/libraries/BlueHartwin/BlueHartwin.h:19:10: note: no known conversion for argument 2 from 'void (BlueHartwin::*)()' to 'CmdFuncPtr {aka void (*)()}'
exit status 1
Errore durante la compilazione per la scheda Arduino/Genuino Uno.
Thanks in advance for help!
Mate, your txSwitchOn/Off methods are instance ones - they require a this to work fine.
On the other side, your CmdFuncPtr is the definition of a function that doesn't depend on anything.
How many such devices (to be supported by your library) is Arduino assumed to handle at any one time?
If it's a single one, then declare everything static, rename the constructot to "static void init() and the destructor to "static void disconnect()", etc. You will have the class acting as just a naming context for your functions (all static).

passing a class member function: type issues

I use the AccelStepper library in my Arduino project, the library has a constructor, with functions as parameters:
AccelStepper(void (*forward)(), void (*backward)());
In the main sketch, this is the code used:
void forwardstep() {
AFstepper->onestep(FORWARD, stepType); //some code to move the motor
}
void backwardstep() {
AFstepper->onestep(BACKWARD, stepType); //some code to move the motor
}
AccelStepper stepper(forwardstep, backwardstep);
as long as this code is in the main sketch, everything works well.
I have created a class that has an AccelStepper object and the forwardstep() and backwardstep() functions as members, but I cannot pass the functions to the constructor of AccelStepper:
.h file:
#define IICADDRESS 0x60
class FilterWheel : public Device
{
public:
FilterWheel();
void forwardstep();
void backwardstep();
void (*fwdstp)(); //function pointer
void (*bckwdstp)(); //function pointer
private:
//Adafruit Motor Shield object
Adafruit_MotorShield AFMS;
//Adafruit Stepper Motor object
Adafruit_StepperMotor *AFstepper;
//AccelStepper wrapper
AccelStepper stepper;
};
.cpp file:
#include "FilterWheel.h"
//constructor
FilterWheel::FilterWheel()
{
fwdstp = &FilterWheel::forwardstep;
bckwdstp = &FilterWheel::backwardstep;
Adafruit_MotorShield AFMS (IICADDRESS);
Adafruit_StepperMotor *AFstepper = AFMS.getStepper(200, 1); //M1 M2
//AccelStepper stepper(forwardstep, backwardstep); //doesn't work
AccelStepper stepper(fwdstp, bckwdstp); //works only if fwdstp = &FilterWheel::forwardstep; and bckwdstp = &FilterWheel::backwardstep; are commented out
}
//go 1 step forward
void FilterWheel::forwardstep() {
AFstepper->onestep(FORWARD, stepType);
}
//go 1 step backward
void FilterWheel::backwardstep() {
AFstepper->onestep(BACKWARD, stepType);
}
when I try to pass the functions directly,
AccelStepper stepper(forwardstep, backwardstep);
the compiler shows the following error:
FilterWheel.cpp:34: error: no matching function for call to 'AccelStepper::AccelStepper(<unresolved overloaded function type>, <unresolved overloaded function type>)'
AccelStepper.h:AccelStepper(void (*)(), void (*)())
AccelStepper.h:AccelStepper(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, bool)
AccelStepper.h:AccelStepper(const AccelStepper&)
Error compiling
when I attach the functions to the function pointers,
fwdstp = &FilterWheel::forwardstep;
bckwdstp = &FilterWheel::backwardstep;
AccelStepper stepper(fwdstp, bckwdstp);
the compiler shows these errors:
FilterWheel.cpp:In constructor 'FilterWheel::FilterWheel()'
FilterWheel.cpp:22: error: cannot convert 'void (FilterWheel::*)()' to 'void (*)()' in assignment
FilterWheel.cpp:23: error: cannot convert 'void (FilterWheel::*)()' to 'void (*)()' in assignment
Error compiling
how can I solve this issue?
forwardstep() and backwardstep() are non-static member functions, so this fwdstp = &FilterWheel::forwardstep; is a pointer to member function, it can't be converted to pointer to function because it needs an object to call it on.
You have to make your functions static or standalone.