1

Is it possible to query the pin-out and each pin's attributes at run-time with Arduino?

If not, can it be done at compile-time?

Finally, if not, how can I incorporate this kind of information into my project to avoid completely rewriting my program for each possible Arduino model?

I am looking for something like this:

PinProperties props= getPinProperties(pinNumber);

props.supportsDigitalInput();
props.supportsDigitalOutput();
props.supportsAnalogInput();
props.supportsAnalogOutput();
props.supportsPWM();
props.analogInputBits();
props.analogOutputBits();
props.pullupResistance();
props.pulldownResistance();

etc.

NOTE: This question is similar and I might use the board model to look up a pre-stored pin-out.

migrated from electronics.stackexchange.com Jan 14 '17 at 23:59

This question came from our site for electronics and electrical engineering professionals, students, and enthusiasts.

  • I did not know about it! Moderators, please migrate this question! – Lennart Rolland Jan 14 '17 at 22:22
  • It's a nice thought, but I'd suggest this could most practically only be done at compile time (selecting an Arduino model based on cpu ID). The only situation where you'd actually need this would be if you deployed the same firmware image to multiple cpu ID's ...but that seems beyond the expectations of the Arduino dev environment. – Jack Creasey Jan 14 '17 at 22:34
  • I am actually going this route in my project. The idea is to abuse Arduino to the benefit of the ease of use for end user. – Lennart Rolland Jan 14 '17 at 22:36
1

pins_arduino.h has some standard macros that can be used for some of what you're looking to do. Using the arduino:standard variant used by Uno for example:

https://github.com/arduino/Arduino/blob/1.8.1/hardware/arduino/avr/variants/standard/pins_arduino.h#L35:

#define digitalPinHasPWM(p) ((p) == 3 || (p) == 5 || (p) == 6 || (p) == 9 || (p) == 10 || (p) == 11)

Or if you want to use your naming scheme:

#define supportsPWM(p) digitalPinHasPWM(p)

After that it gets a bit more sketchy:

https://github.com/arduino/Arduino/blob/1.8.1/hardware/arduino/avr/variants/standard/pins_arduino.h#L28

#define NUM_DIGITAL_PINS 20

So, assuming that Arduino digital pins will always be numbered consecutively from 0 and any pin that supports digital input also supports digital output(which is the case in any variant I'm familiar with), you could use that to write some macros:

#define supportsDigitalInput(p) ((p) < NUM_DIGITAL_PINS)
#define supportsDigitalOutput(p) supportsDigitalInput(p)

https://github.com/arduino/Arduino/blob/1.8.1/hardware/arduino/avr/variants/standard/pins_arduino.h#L29

#define NUM_ANALOG_INPUTS 6

Could be used to write this macro(with numbering assumption):

#define supportsAnalogInput(p) ((p) < NUM_ANALOG_INPUTS)

Note that this will not work for the An analog pin names(e.g. A0 vs 0).

As for:

props.supportsAnalogOutput();
props.analogInputBits();
props.analogOutputBits();
props.pullupResistance();
props.pulldownResistance();

I'm don't know of pre-existing code for those. There is probably a way to get it for the first three in an architecture specific manner. The last two you'd most likely need to get the information from datasheets for all of your target microcontrollers and define then using processor specific macros.

0

There is no strong relation with pin numbering and the hardware as far as I know.

To be more specific, the datasheet tells you what registers can be used for what functions. The microcontroller does not neccesarily know what registers it has or what functionality it's registers have.

You could make your own library or class for a pin.

I would go by something like:

Pin input1 = new Pin(.....);

if(input1.isAnalog()){
   input1.setupAnalog();
}

if(input1.analogIsReady()){
   input1.readAnalog();
}

Instead of having a "pinproperties" object for a pin.

You'll have to look how you want to make the class. You can create one single class that has all functions and just checks if there is an implementation for that pin.

You may go by classes like:

class pin

class analogPin extends pin

class pwmPin extends pin

However, this may fail if your analog pin doesn't support the regular "pin" functions (like I/O).

Theoretically you could use C++'s multiple inheritance to inherit things as I/O, PWM and Analog, but I've heard that it doesn't perform very well on embedded targets.


Alternatively you could make a list of pins that support PWM. And a list of pins that support Analog. And a list of pins that support I/O.

When a person (runtime) tries to set a pin's state, you can check if that pin supports I/O, but I'm not sure what behaviour you'll expect if one tries to set a pin that doesn't support that option.

0

Finally, if not, how can I incorporate this kind of information into my project to avoid completely rewriting my program for each possible Arduino model?

The libraries are designed so that you don't really need to know that. One issue is the relationship between the chip pins and the board pins. Just as an example, pin 19 on the Atmega328P goes to the board pin 13 (digital pin 13) on a Uno.

If your program needs a couple of digital inputs and a couple of digital outputs, you could use (say) D2 and D3 as inputs and D4 and D5 as outputs. Then let the underlying libraries work out which chip pin that is, and configure it correctly when you use digitalRead, digitalWrite and pinMode.

You can self-query for the chip type (for example here) however that doesn't tell you what board the chip is mounted on.


to avoid completely rewriting my program for each possible Arduino model

What are you envisaging that would require a complete rewrite? Many libraries and projects are written to work on multiple boards with only minor changes (if any). You can detect the processor type at compile-time.

I simply don't see where "complete rewrite" comes into it. Use functions to abstract out the parts that interface with pins (as digitalRead, digitalWrite and pinMode already do) and a few constants at the start of the code to indicate which pins you have chosen for this particular board.

  • Sorry ,I should have explained better. My program is datadriven so that the serial protocol will tell it which pins to use for what. To make that happen it needs to know which pins are available, and what they can be used for. So instead of maintaining many images, I would like to maintain only ONE that adapts to the current hardware. – Lennart Rolland Jan 16 '17 at 0:09
  • I see. Well, different Arduinos have different processors. For example ones like the Atmega2560 have different addressing models internally than the chips with less RAM. Your goal of sharing a single executable amongst various processors is probably not very achievable. It's like hoping to run Windows software on OS/X. – Nick Gammon Jan 16 '17 at 4:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.