Skip to content

Instantly share code, notes, and snippets.

@rwaldron
Last active August 29, 2015 14:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rwaldron/8ca22cd834970e074f15 to your computer and use it in GitHub Desktop.
Save rwaldron/8ca22cd834970e074f15 to your computer and use it in GitHub Desktop.

Good Idea? Bad Idea?

The Arduino programming environment is bootstrapped with many preprocessor definition contant values, specifically created to make the programming experience more accessible to non-programmers. Some specific examples include:

  • Analog Pins:
    • A0: 14
    • A1: 15
  • Modes:
    • INPUT: 0
    • OUTPUT: 1
  • Values:
    • HIGH: 1
    • LOW: 0

...And many more.

Should Johnny-Five expose similar global constants?

Please post thoughts in the comments. I'd like to flesh out the lists below before making a decision.

Pros

  • Easily memorized by users
  • Increased accessibility for those familiar with Arduino IDE programming
  • Potentially reduce user code errors (?)

Cons

  • Global scope pollution
@getify
Copy link

getify commented Apr 26, 2015

I think you definitely should provide these constants, but not as globals. Can they be on a namespace? Like J5.INPUT or whatever?

@addyosmani
Copy link

Is there value in keeping these pure globals? If not, I'd echo Kyle's comments on opting for a namespace for these constants to limit scope pollution.

@dtex
Copy link

dtex commented Apr 26, 2015

If these are not consistent across all micro-controllers then you have a new wrinkle and it is something that would have to be implemented at the IO level, not in J5. Also I think of Firmata as our "first class" citizen, not Arduino. That's where we should look for guidance. Do these constants make sense or already exist in Firmata? If so, then we can go for it but all the IO's are essentially Firmata compatibility layers and this would have to be addressed in each and every one.

HIGH and LOW are easy enough, but pins and modes could vary. I think you'd need an audit of all the devices supported by Johnny-Five to make sure you aren't introducing something that would be self contradictory in some cases.

@allenwb
Copy link

allenwb commented Apr 26, 2015

I also agree that they should be name-spaced. How about a controller namespace object (CTL?) that contains both generic (common to all controllers) values and controller-specific values. May be the same as what @dtex is talking about as IO. I don't have the familiarity with J5 to know whether or not that is structurally the right level.

@mcdonnelldean
Copy link

Like the idea but as above only if namespaced

@soundanalogous
Copy link

Regarding analog pins, when using Firmata, you won't know the mapping until the configuration query and analog mapping response has returned so I'm not sure how you could use a constant since the mapping of analog pins to digital pins differs per board. Same with constants such as SCL, SDA, etc. The mapping differs by board and there is no way to know what the board from the Firmata client (J5) until you receive a response from the board.

@soundanalogous
Copy link

Compare the pins_arduino.h file you referenced for the standard (ATMega328) arduino variant to the pins_arduino.h file for the Arduino Leonardo and the Arduino Mega and you'll see how the mappings are not consistent across boards. It would be safe to create (namespaced) global constants for things like pin modes and common values (HIGH / LOW) but that's probably about it.

@WebReflection
Copy link

my 2 cents: be pragmatic, and keep it simple. A1 is analog 1 everywhere on microcontroller, and dedicated JavaScript engines are doing just fine these days with these simple conventions: http://www.espruino.com/Reference#_global

Sure, the namespace is cool and future proof and ... you know, nobody is going to name something A1 or HIGH and LOW in a different way so, I'd repeat my thoughts: be pragmatic, and keep it simple

@WebReflection
Copy link

@soundanalogous when you develop for a micro controller you really do know which one is that, you don't ping or use ports by accident and you might eventually rely on the equivalent of a navigator.userAgent that tells you which board is it so you can alias public global constants.

Someone might think navigator.userAgent is a bad practice and it is comapred to feature detections ... now, you have 30KB in total on Espruino Pico, as example, there it goes your wasted feature detection code: it won't fit in there, as easy as that.

You should know your target, or distaster occurs, accordingly, if A1 points to a different A1 in different boards, I am not sure that's a real concern. HIGH and LOW would improbably be different from 1 and 0

Again, just my thoughts

@jesgundy
Copy link

+1 for namespacing.

@soundanalogous
Copy link

@WebReflection, when using Firmata from a client (J5 in this case) you do not know which board you are dealing with until you query it. At least with the way Firmata currently works (I know because I am the maintainer of the Firmata library). Obviously you could assign values to A0, A1, etc once the query returns and you have the mapping. This is Firmata-specific. You would not have this issue when using J5 with board-specific plugins.

@soundanalogous
Copy link

One way to get around this (when using Firmata and J5) would be to add an option to declare the board (or architecture) used when creating a new instance of five.Board. That would also eliminate the need for the configuration query and analog mapping requests and would ultimately allow for a much faster startup time upon connecting to the board. If the board type is not specified, then fall back on the configuration query and analog mapping request.

@rwaldron
Copy link
Author

Regarding analog pins, when using Firmata, you won't know the mapping until the configuration query and analog mapping response has returned so I'm not sure how you could use a constant since the mapping of analog pins to digital pins differs per board.

@soundanalogous thanks for this reminder.

@phated
Copy link

phated commented Apr 26, 2015

Probably expose on the board and receive from the IO implementation. You could make them getters on board that proxy through to the IO class or attach during bootstrapping.

@WebReflection
Copy link

You could make them getters on board that proxy through to the IO class or attach during bootstrapping.

exactly my thoughts here too

A namespace wouldn't solve anything in this scenario anyway, would be just delegating the problem to j5. instead of just global

@boneskull
Copy link

GLOBAL ALL THE THINGS

@fivdi
Copy link

fivdi commented May 2, 2015

Given that J5 can support multiple different boards concurrently (I think), it's probably not a good idea for constants like A0 through An to be global. Different boards will have a different number of analog inputs. Exposing them on the board as suggested by @phated is a better way to go.

Lots of the constants in the header files linked to above are very specific to a particular microcontroller. Most of the constants are probably not needed and if they are, exposing them on the board is also the better way to go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment