Go Down

Topic: Not understanding toggle code (Read 2 times) previous topic - next topic


that there are "working" code examples out there in the forum posts
and in libraries that are using 0 and non zero to set the output pin state.

Yes and in every other language I have programmed in Boolean variables use this convention.

and that is why the core developers like Diligent/chipkit and Maple
have implemented their DigitalWrite() routines with the same HIGH/LOW values and assumptions.

This convention has been in place long before the Arduino existed, it is the normal way of doing things.

But doing things like this come with added risk that if ever the defines change,
the code may stop working as expected.

Well the code will continue to work but it will only be when you recompile the code you will get trouble in the unlikely event that some idiot decides to overthrow decades of convention. Anyone trying to write portable code on an arduino is going to have to give up the pin orientated view of the outside world.
Remember we are not controlling a nuclear power plant but flashing an LED on and off.  

Code portability has its place but only when you know it is going to be portable. Too many bytes and CPU cycles are wasted trying to make things portable that will never ever move.


Is there a binary logic chip made that uses other than 0 for FALSE/LOW and 1 for TRUE/HIGH?
Memory, controller, processor, register?

But we are not talking about chips.
We are talking about how to write software to use a software API function.
The s/w API says use these defines: "HIGH" and "LOW" to get things done.

Don't get hung up on this specific digitalWrite() function call and how HIGH and LOW
map to the output states of the pin.

BTW, there are some chips that use separate set and clear registers.
In that situation, 1 bits written to a clear register will actually clear bits not set them.
And actually there are examples where true was defined as 0 and false was 1 in software
from the 80's on at least one RISC processor - but lets not delve down there.

Again, it is the concept of properly using an API as it is defined vs stepping outside the defined API
to use it ways that it is not defined.

You guys are getting all hung up over this one simple function.
I'm trying to express a reason to follow an API which a much bigger concept.

To help illustrate, lets look at some other API function.
Maybe something like:

setpixel(int x, int y, int color);

Where color can be WHITE or BLACK.
Without looking could you be sure the values for BLACK or WHITE were? No....
If you were to take a sneak peak at what BLACK and WHITE are, maybe you could write some
sightly better code that uses their raw values rather than use the defines.
Or that took advantage of the library code assuming one color when the value was zero and
used the other other color for any non zero value.

But then I re-write the library to get ready for additional colors and I change the values for
BLACK and WHITE to other values. Those that use BLACK and WHITE vs their raw values will
be fine. Those that went around using using the defines or taking advantage of the library
working a particular way when say the color was non zero will get burned.

C++ could solve this by creating a function that only accepted the proper defines/enums
to ensure that people didn't bypass using the proper types on functions like digitalWrite(),
but today digitalWrite() is a C function using only native types and so there is no way to enforce
that the "val" argument is of the type vs some calculated numeric type made from assuming
the values of of the defines.

--- bill


Is it conceivable that in any implementation of any language the HIGH will not be the logical inverse of LOW? These are hardware concepts and these nimby pimby software types had better get their head round that fact!

In general, when you code to any API you should avoid making any assumptions about the behaviour of that API that are not specified as part of the API. It may be that in this case you know (or assume) that HIGH and LOW correspond to a bit being set or unset in a hardware register. You may even know (or assume) which bit is set, and which bit state corresponds to the HIGH output. But it is poor practice to embed that assumption in your code. By encouraging people to do that, you're teaching them bad habits.
I only provide help via the forum - please do not contact me for private consultancy.


I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Udo Klein

@berrybap: although I agree that one should not rely to much on implementation details I disagree with you reasoning.

1) Please notice that smilies indicate humor.

2) You write
(Udo: All the examples that use exclusive ORing, would break if LOW was not 0)
. This is not true. For which values of HIGH and LOW would this
Code: [Select]
digitalWrite(pin, state^= (HIGH^LOW));

3) You seem to pick this up intentionally. IMHO teaching your "IF" style is no better. It promotes an imperative style and it does not consistently deal with undefined values. Notice: not your code example but the IF style.

4) There is not intrinsic API documentation for the Arduino. All documentation is outside Arduino.h. If you look into the header file you will immediately notice that the signatures are flawed:
Code: [Select]

void digitalWrite(uint8_t, uint8_t);
int digitalRead(uint8_t);

digitalRead delivers values of a different type than its counter part digitalWrite. At no place in the file is there any hint that the macros "HIGH" and "LOW" are to be used with these functions they are not even placed closely. So how would anyone correctly abstract from such an API?

Thus you refer to external "API specification". But which one? As it is this API requires developers to look up the code.

5) Your API example with PWM extensions is completely made up. Typically the method/function names should hint at their use. Extending functions that are prefixed with "digital" to allow for PWM seems not like a reasonable API extension to me. It actually changes the API semantics.

6) The "?" Operator is not a macro. It is an operator. IMHO the use of this operator should be more widely understood.
Check out my experiments http://blog.blinkenlight.net

Go Up