New User with Compiler Questions

Hello,

I'm still waiting for a certain Arduino kit to be back in stock so I don't have one yet, but I'm playing with the compiler and learning the software anyway even without one.

I'm trying to understand how the compiler "knows" which pin is which and what it's supposed to to. I have tried typing the wrong variable names and the compiler understands that there is an error - for example it doesn't accept high but does accept HIGH for a digital output. But it doesn't seem to have the same smarts about the pins and the variable assigned to them. Maybe it makes sense to someone out there though. I have an example that compiles with questions inserted, if anyone could help me understand this aspect I'd appreciate it.


void setup() {

}

void loop() {
int sensorValue = analogRead(44000); //why does this function accept 44000 as the pin # when there is no such pin?
int digital = digitalRead(A0); //Why does digitalRead accept an analog pin variable (A0)
digitalWrite(0,34770); //why does digitalWrite accept a number and not the variable HIGH or LOW?
//What does the number mean in this case?
analogWrite(8,100); //why is this accepted when pin 8 is not PWM capable?
}

Thanks.

Well my answer would be, the compiler and framework only takes you so far...
and the Arduino framework wants to leave options open

E.g. maybe there would someday be an arduino with more than 16 or 256 or 32768 digital pins
You can use an "analog pin" as a digital pin if you choose
(As to digitalWrite( int, int) I am actually with you there I tend to think in terms of digitalWrite(int, bool))

But also,
why can you park a sofa in your garage?
why can your front door accept a motorcycle?
why does your bank allow you to overdraft your account and then charges you a fee?
etc etc

  int sensorValue = analogRead(44000); //why does this function accept 44000 as the pin # when there is no such pin?

The compiler does not know that your Arduino does not have 44000 pins. It is the programmers responsibility to not make these kind of mistakes.

  int digital = digitalRead(A0); //Why does digitalRead accept an analog pin variable (A0)

Actually, A0 is an alias for using an analog pin as a digital pin, so this statement is perfectly correct. What is wrong is your understanding that A0 refers to an analog pin. It does not. 0 refers to analog pin 0. A0 refers to analog pin 0 used as a digital pin.

Now, the analogRead() function is smart enough to know that A0 (14 on a 328-based Arduino) is supposed to have been 0, and it will read from the correct pin.

  digitalWrite(0,34770); //why does digitalWrite accept a number and not the variable HIGH or LOW?
                                 //What does the number mean in this case?

Because HIGH and LOW are constants. The function has to be written with a variable type in the definition, so the developer chose (incorrectly, in my opinion) int. Whatever type is chosen has to accept any value that could be assigned to a variable of that type.

In most situations, the function would return an error if the input was not in range (LOW to HIGH), but how is an embedded processor supposed to deal with an out of range value? Ignoring it is the usual answer, but that is not always satisfactory, either.

  analogWrite(8,100); //why is this accepted when pin 8 is not PWM capable?

It is, on a Mega. Again, it is up to the programmer to call functions with valid input.

johncc:
Well my answer would be, the compiler and framework only takes you so far...
and the Arduino framework wants to leave options open
E.g. maybe there would someday be an arduino with more than 16 or 256 or 32768 digital pins

Yes, but you select your board in the IDE, hence I would think the compiler would know what pins are used for what ... but it apparently it doesn't apply in that case. I mean if it can discriminate between high and HIGH it seems it would know that an analog variable would not apply to a digital pin.

You can use an "analog pin" as a digital pin if you choose
(As to digitalWrite( int, int) I am actually with you there I tend to think in terms of digitalWrite(int, bool))

I'll look into that.

But also,
why can you park a sofa in your garage?
why can your front door accept a motorcycle?
why does your bank allow you to overdraft your account and then charges you a fee?
etc etc

Well, of course the answer is that I am alive and a human and can do irrational and odd things if I choose (like the bank). :slight_smile:

I learn by "breaking things" so I wanted to see how the compiler behaved before I get my Arduino kit.

void setup() {

}

void loop() {
int sensorValue = analogRead(44000); //why does this function accept 44000 as the pin # when there is no such pin?

I believe analogRead() is expecting a byte size variable passed to it, so this is probably just the lower 8 bits of your 44000 value to determine what pin number you are wishing to control?

int digital = digitalRead(A0); //Why does digitalRead accept an analog pin variable (A0)
Because A0 is just a #define which substitutes the value 14, so it's performing a digitalRead from pin 14 which is the same as analog pin 0.

digitalWrite(0,34770); //why does digitalWrite accept a number and not the variable HIGH or LOW?
//What does the number mean in this case?
digitalWrite() just looks to see if the value is equal to 0 and if so sets pin to LOW, otherwise any other value
causes pin to be set to HIGH.

analogWrite(8,100); //why is this accepted when pin 8 is not PWM capable?
}
If analogWrite() determines that the pin number given is not a PWM pin it sets output pin High is value is >127 or LOW if value is <128.
Lefty

Thanks.

retrolefty,

Thanks for the info I'll study up on your answer. Thanks much.

Yes, but you select your board in the IDE, hence I would think the compiler would know what pins are used for what

Selecting the board determines what pin-to-port mapping file is included, and tells the linker what to develop the hex file for. It tells the compiler nothing.

I mean if it can discriminate between high and HIGH it seems it would know that an analog variable would not apply to a digital pin.

It knows whether it has seem the symbol "high" or the symbol "HIGH". It knows nothing about an Arduino. (It being the compiler.)

I learn by "breaking things" so I wanted to see how the compiler behaved before I get my Arduino kit.

In strange and mysterious ways... 8)

PaulS:
In strange and mysterious ways... 8)

True. If I just had that kit by now I probably wouldn't even had tried these things. :slight_smile:

I'm a model railroader and I plan on trying to use the Arduino on the layout in some fashion. Right now it's a solution in need of a problem but I'm sure I can remedy that in due time.

Right now it's a solution in need of a problem but I'm sure I can remedy that in due time.

Oh, so you ordered a Due? Or, should that be in Uno time?

PaulS:

Right now it's a solution in need of a problem but I'm sure I can remedy that in due time.

Oh, so you ordered a Due? Or, should that be in Uno time?

LOL. Well, the kit will have an Uno -

modeller:
I'm a model railroader and I plan on trying to use the Arduino on the layout in some fashion. Right now it's a solution in need of a problem but I'm sure I can remedy that in due time.

Should be fun! I was blown away by this model airport YouTube

Some programming languages support the concept of constrained types and would prevent invalid values from being accepted by the compiler. The 'C'/C++ language doesn't do this. As long as the valoue you supply is of the correct type (or can be converted into the correct type automatically by the compiler) the compiler will accept it. If the compiler accepts it, then the effects of passing in invalid values depend on the run-time implementation of the functions being called. The Arduino run-time library seems quite robust and will probably try to do something sensible in most cases, but it will always be possible to write, compile and run code which is logically nonsense, but valid as far as the compiler and runtime implementation are concerned. Your job as a programmer is to avoid or eliminate those problems.

johncc:
Should be fun! I was blown away by this model airport YouTube

Oh yea I've seen it - that's crazy. I attached a smal pic of a recent scene project of mine.

PeterH:
Some programming languages support the concept of constrained types and would prevent invalid values from being accepted by the compiler. The 'C'/C++ language doesn't do this. As long as the valoue you supply is of the correct type (or can be converted into the correct type automatically by the compiler) the compiler will accept it. If the compiler accepts it, then the effects of passing in invalid values depend on the run-time implementation of the functions being called. The Arduino run-time library seems quite robust and will probably try to do something sensible in most cases, but it will always be possible to write, compile and run code which is logically nonsense, but valid as far as the compiler and runtime implementation are concerned. Your job as a programmer is to avoid or eliminate those problems.

Yes, thanks for the info. I have an account here now and I'm sure I'll be asking more questions. I'll still have to learn in a "virtual" way, so to speak, until the kit I want is in stock.

One can define and instantiate different things depending on which board is targeted, can't you? E.g., hardware serial instantiates more serial objects depending on the target's UARTs:

#if defined(UBRRH) || defined(UBRR0H)
  extern HardwareSerial Serial;
#elif defined(USBCON)
  #include "USBAPI.h"
//  extern HardwareSerial Serial_;  
#endif
#if defined(UBRR1H)
  extern HardwareSerial Serial1;
#endif
#if defined(UBRR2H)
  extern HardwareSerial Serial2;
#endif
#if defined(UBRR3H)
  extern HardwareSerial Serial3;
#endif

I suppose you could define constants like "PIN47" that would be valid only for a particular board if you were really keen on providing compile-time hardware constraints - not that I think it would be a good idea!