Go Down

Topic: Documentation should be improved to distinguish between macros and functions! (Read 1 time) previous topic - next topic

VinzC

Hi all.

I'm a happy user and hacker with Arduino. My next projects will be based on AVR and I enjoy Arduino for I now have a test bench and a hardware development environment that is absolutely awesome.

Now there's one thing that bugs me and it's the documentation.

I am a developer and C/C++, PHP, Lua, Python are my languages of reference. I do really hate to see two lines of code when only one says it all. I'm a great one-liner, if you like.

I've just spent two hours trying to figure out why this simple code didn't work:
Code: [Select]
int value = 0x30;

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(57600);
  Serial.println("Awaiting your orders...!");
  Serial.setTimeout(50);
}

void loop()
{
  if (Serial.available() > 0)
  {
    // Read integer
    value = constrain( Serial.parseInt(), 0, 255 );
    // Then flush input buffer
    while ( Serial.available() > 0 )
      Serial.read();
    Serial.println( value, DEC );
  }
}

The symptom: using the serial monitor, whether I use line termination or not, the monitor always shows a zero echoed by the Arduino:
Quote from: Serial Monitor
Awaiting your orders...!
0
0
0
0
I could type any integer value (1, 3, 12, 50), only a zero was echoed, obviously after a timeout, which I also wondered why.

After fiddling around, cutting through the code, swearing and staying puzzled for a while, I then tried this:
Code: [Select]
    value = Serial.parseInt();
    value = constrain( value, 0, 255 );

and *BAM* it worked!

I then *guessed* my mistake (if there was any) was to believe constrain() is a function. If it is a macro then it makes sense: a macro would call no less than twice Serial.parseInt() in such a code. But the documentation nowhere states what kind of call constraint() is:
Quote from: https://www.arduino.cc/en/Reference/Constrain
Reference   Language | Libraries | Comparison | Changes

constrain(x, a, b)

Description

Constrains a number to be within a range.

Parameters

x: the number to constrain, all data types
a: the lower end of the range, all data types
b: the upper end of the range, all data types

Returns

x: if x is between a and b
a: if x is less than a
b: if x is greater than b
My errancy would have been avoided *if only* the documentation specified what constraint *really* is for it's certainly NOT a function. I now tend to believe it's a C-like macro.

So please, clearly state in the documentation whether those... things actually are functions or macros. Traps like this one are easy for newcomers to fall into. Just like I did.

Otherwise thanks a lot for such a great product. It's a bliss for electronics hobbyists and engineers as well.

pert

I now tend to believe it's a C-like macro.
That's correct. It's in hardware/arduino/avr/cores/arduino/Arduino.h:
Code: [Select]
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))

VinzC

Thanks. Pleased I guessed right. Now I think there should be distinct sections: macros and functions -- having to consult the header files in order to raise the online documentation ambiguities is counter-intuitive and should be avoided, especially if no one knows where ambiguity lies...

One might argue that would lead to confusion, e.g. people asking what macros and functions are, which is correct... only if no clarification is made. But all in all isn't it preferable to people wondering why their program doesn't work indefinitely just because the online documentation provides no appropriate info?

Do you agree?

Coding Badly


A different (arguably better) choice is to update the macros.  A detailed discussion is available here...
http://forum.arduino.cc/index.php?topic=84364.0


pert

I think there should be distinct sections: macros and functions
I don't think separate sections are needed because some of the macros can be safely used the same as a function, for example another one in Arduino.h:
Code: [Select]
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
There's no need for a beginner to know if that's a macro or a function. The reference needs to be accessible to someone who is just plugging in their Arduino for the first time and has almost no programming experience, breaking things into macros and functions just adds another layer of confusion. However, I do think that the reference should try to note any limitations such as the one you have encountered with macros and functions. That one would be very confusing to a beginner and many of the macros will cause this problem. The introduction to each reference page needs to be simple and short but after that should provide as much information as necessary(including data types). This way the user can get the basic description quickly and then if they run into problems come back for the details.
having to consult the header files in order to raise the online documentation ambiguities is counter-intuitive and should be avoided, especially if no one knows where ambiguity lies...
I completely agree with that. Just finding the right source file is going to be fairly difficult for a beginner.

VinzC

I don't think separate sections are needed because some of the macros can be safely used the same as a function, for example another one in Arduino.h:
Code: [Select]
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
Maybe a diffferent section is too much indeed. However...

There's no need for a beginner to know if that's a macro or a function.
With that, I totally disagree. How can you learn a programming language without making the difference between a macro (i.e. a #define in C) and a function? We've all been beginners one day. Why wouldn't Arduino documentation *also* teach that aspect of C?

Besides, the documentation has already tipped into the C #define, carefully focussing only on *constants*, so to that extent, it's already too late: one step was made, let's make the other. Arduino is enough to make curious and open minded people dig further, so, well, let the documentation be complete: expose what and how macros are defined and the ambiguity is raised.

And quite honestly, if beginners can understand what a define is, they won't even blink if you add macro definitions. Nothing is more frustrating than being hidden details to the one who needs them.

A different (arguably better) choice is to update the macros.  A detailed discussion is available here...
http://forum.arduino.cc/index.php?topic=84364.0
Right! That's also another approach.

rinkrides

I agree with VinzC completely. I recently had a very hard time with digitalRead() and a scenario when i tried to read voltage and average from a current sense resistor while the PWM pin was active, NOT KNOWING that digitalRead() will disable PWM on the pin i was simply trying to enable a sampling for loop that should have worked just fine BECAUSE THIS CAVEAT WAS NOT EVEN MENTIONED ON THE LANGUAGE REFERENCE while i was REFERENCING the digitalRead() function within the OFFICIAL reference. There should be a major edit to the reference for those who want to dig deeper than just blinking an LED or running the demo's.

Caveats should be listed lower on the function pages along with what type the function/macro is, clock cycles for noobs that should maybe be coding certain loops in assembly or using bit shifts instead of divide macro/function, whatever it is to speed up execution time.

Reference should have two distinct sections, one for noobs to arduino who can safely get by blinking a few LEDs & enjoying the experience of easing into programming in C, & another section for more advanced users who may not be aware of things and facts like divide is emulated with a 40 or so line function/macro (i don't know the ramifications of either to my program).

Spending DAYS googling for forum posts on an explanation of why functions work counter intuitively or seem back asswards (see: MIN(), MAX() in reference) when all this confusion and delay could be avoided by givinga bit more NEEDED info right in the reference. Noobs will gloss over more comple things in the refereence and focus on the details in which they were there in the reference for. You, the developers of arduino have made a transistion from digital gates to programming on MCU's very easy indeed. But YOU telling me "this is all you need to know about this "function" and dont worry about the caveats like execution time or things like divide is emulated or that digitalRead() disables the PWM pin i'm trying to read just leads to frustration, MORE confusion, and delays. Most would not be turned away from Arduino as they do with their brilliant ideas simply because their programs SHOULD work according to the REFERENCE, but do not because they are macros and not functions!
Electronics Engineering, "EE=MC^(OMG x WTF?!)"
Professional Auto Collision/Custom tech

68tjs

I think the root of the problems is that the majority of users refuse to read the datasheet of microcontroller used.

 The datasheet of AVR clearly indicates that the timers can take control of some pins and not just for the PWM.
 When it is the timer that controls a pin it is obvious that we can no longer use this pin "classically" without stoping the timer.

Regrettably Arduino has not laid down rules for the documentation of libraries.
 For example Arduino would have itself used and demanded that all the libraries are documented with Doxigen, users would do less error due to ignorance.

The past is the past  but there is still time to impose rules for new libraries or for updates.
If Arduino would actually work hand in hand with the community, Arduino should organize a poll on this it would be good to include in the documentation of libraries.

Go Up