Error compiling for ArduinoIoTCloud with M5StickCPlus
-
I have been using Arduino IoT Cloud successfully with an M5Atom for a while, creating Things with cloud variables controlled by Dashboards, such as using a button on a Dashboard change the color of the LED. I tried doing something similar with an M5StickCPlus with a simple sketch using the template provided by IoT Cloud to change the color of the LCD display:
#include "arduino_secrets.h" /* Sketch generated by the Arduino IoT Cloud Thing "Untitled" https://create.arduino.cc/cloud/things/e393cc1c-d5b7-48bb-8a27-521dxxxxxxx Arduino IoT Cloud Variables description The following variables are automatically generated and updated when changes are made to the Thing bool button; Variables which are marked as READ/WRITE in the Cloud Thing will also have functions which are called when their values are changed from the Dashboard. These functions are generated with the Thing and added at the end of this sketch. */ #include "thingProperties.h" #include "M5StickCPlus.h" void setup() { M5.begin(); // Defined in thingProperties.h initProperties(); // Connect to Arduino IoT Cloud ArduinoCloud.begin(ArduinoIoTPreferredConnection); void loop() { ArduinoCloud.update(); // Your code here } /* Since Button is READ_WRITE variable, onButtonChange() is executed every time a new value is received from IoT Cloud. */ void onButtonChange() { // Add your code here to act upon Button change if (button) M5.Lcd.fillScreen(RED); else M5.Lcd.fillScreen(BLUE); }
When I compile this, I get the following error:
c:\Users\xxx\Documents\Arduino\libraries\M5StickCPlus\src/utility/In_eSPI.h:952:52: error: macro "setAttribute" passed 2 arguments, but takes just 1 void setAttribute(uint8_t id = 0, uint8_t a = 0);
The problem is that
ArduinoIoTCloud.h
includes a fileproperty/Property.h
that defines three macros, includingsetAttribute
#define appendAttributesToCloud() appendAttributesToCloudReal(CborEncoder *encoder) #define appendAttribute(x) appendAttributeReal(x, getAttributeName(#x, '.'), encoder) #define setAttribute(x) setAttributeReal(x, getAttributeName(#x, '.'))
Unfortunately, there is a class member function called
setAttribute
in the library fileM5StickCPlus/src/utility/In_eSPI.h
// Set or get an arbitrary library attribute or configuration option void setAttribute(uint8_t id = 0, uint8_t a = 0); uint8_t getAttribute(uint8_t id = 0);
Because the macro from the ArduinoIoTCloud library is included globally, it ends up getting used in place of the correct function (which has 2 arguments).
Whose "fault" is this and what should be the fix? In general, I think it's not good form to include a global macro in a library, especially one with a name like
setAttribute
that could easily match something in user code that includes that library. So I decided to change my local copy of the ArduinoIoTCloud library and replace the macro name withAIOTC_setAttribute
(as well as prefixing the other two macros withAIOTC_
), and then modify all of the files inproperty/types
that use this macro to match.Hopefully someone finds this helpful. I'm going to post this over on the Arduino forum as well, as I think these global macros should be replaced by something safer.