Compile problems in using millis() as a timer delay

Using the Arduino IDE to code:
I have a function that creates a delay. code is below.
unsigned long CM =0;
unsigned long PM = 0;
int IV = 15;
int De = 0;
int ZZ = 0;
Void Delaytimer () {
CM = millis();
if((CM -PM) > IV) { // Compile chokes here,"invalid operands of types ‘long unsigned int’ and ‘Pm*’ to binary ‘operator-’
PM = CM;
if (De <= 600) {++De;}
if (ZZ <= 32700) {++ZZ;} else { ZZ = 2;Etherudprest();}
this function works on all Arduinos that I have programmed, but not on the XIAO.
does the XIAO use a different method for timing?Is there a set of firmware instructions that show what timing words can be used or ???

Hi Unlike

‘PM’ is already defined below.


So how would I know that ? Most if not all of my programming has been with the Arduino Nano, Mega 2560, and Uno. The code works fine on those devices. Is there some kind of reference sheet of commands that Seeed used to make firmware for the XIAO?

Looking a the library file, most variables that I saw were in CAPS. So maybe I should avoid using all caps for variables when using the XIAO.


The compiler printed the following message, so I knew that “PM” was already defined.

C:\Users\username\AppData\Local\Arduino15\packages\Seeeduino\tools\CMSIS-Atmel\1.2.1/CMSIS-Atmel/CMSIS/Device/ATMEL/samd21/include/samd21g18a.h:476:38: error: expected ‘)’ before ‘*’ token

#define PM ((Pm *)0x40000400UL) /**< \brief (PM) APB Base Address */

You should simply adhere to C standards. All uppercase names are not allowed for user programs. These are reserved names for libraries. The same holds for identifiers starting with _.

Thank you, as you may be aware I am a self taught programmer(?), and don’t know all of the rules and conventions that I should know. The Arduino devices make it too easy to code and make the program function with little coding knowledge.

Well, just to be fair, none of the existing C standards disallow capitalised, or _ prefixed variable names in “user” programs.

There is a common convention to use _ prefixed variables in libraries.
There is NO common convention for the capitalised variables.

And IMO, the fact that PM variable is defined in the CMSIS package and a user program has silently shadowed that variable, points to a problem of the build environment, not the user program.

So I would blame the XIAO’s Arduino support package, not the user.

You are correct that all caps identifiers are not disallowed. But it is a common convention starting from K&R not to use all caps for anything except macros. For identifiers beginning with _ you are incorrect:

Reserved identifiers

The following identifiers are reserved and may not be declared in a program (doing so invokes undefined behavior):

  1. The identifiers that are keywords cannot be used for other purposes. In particular #define or #undef of an identifier that is identical to a keyword is not allowed.

  2. All external identifiers that begin with an underscore.

But I have to agree with you that the BSP for the XIAO should not declare variables in the way it does.
But this a common problem with the whole Arduino environment. It tries to hide too much from the user. At first sight this seems to help beginners. But it leads to bad programming style the violates general conventions.
As an example I do mostly certified avionics software. This has to be error free because malfunction could cost lives. I require all my program to compile without any warnings with all compiler warnings enabled. None of the Arduino libraries pass this test. Some of the warning I see are not just innocent warnings but point to potential undefined behavior. I would never use something like this in my professional work.

1 Like

@rbehm you’re correct on the underscore usage, thanks for the background.

On the PM definition- apparently it comes from the CMSIS package. It is supplied by a chip vendor (Microchip) in form of a header file. So it is not, strictly speaking, Arduino’s code.

Apparently, this is a common practice for vendors to make CMSIS definitions that way, e.g. one can find the the STM32’s CMSIS headers things like:

#define DMA1_Channel6       ((DMA_Channel_TypeDef *)DMA1_Channel6_BASE)
#define DMA1_Channel7       ((DMA_Channel_TypeDef *)DMA1_Channel7_BASE)
#define RCC                 ((RCC_TypeDef *)RCC_BASE)
#define CRC                 ((CRC_TypeDef *)CRC_BASE)
#define FLASH               ((FLASH_TypeDef *)FLASH_R_BASE)
#define OB                  ((OB_TypeDef *)OB_BASE)
#define DBGMCU              ((DBGMCU_TypeDef *)DBGMCU_BASE)

Not sure what would be the right best practice here… Refrain from using all-capital defines or variables maybe.

Yes, I would refrain from using all caps. I never use these, simply because of the old convention to use all caps for macros. Especially a macro name used for another identifier leads to confusing error messages.

1 Like