arduino / Arduino

Arduino IDE 1.x
https://www.arduino.cc/en/software
Other
14.14k stars 7.01k forks source link

Using fake pin number #6207

Closed FernandoGarcia closed 7 years ago

FernandoGarcia commented 7 years ago

Hi!

I haven't enough pins in my controller and I need use some fake pin numbers to allow user select the right pin desired if not using a multiplexer.

The problem is that using the pin number as 86 for Arduino Mega the code change pin status of pins 10, 11 or 12.

Here the test code:

void setup() 
{
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(86, OUTPUT);
}
void loop() 
{
  digitalWrite(9, HIGH);
  digitalWrite(10, HIGH); 
  digitalWrite(11, HIGH); 
  digitalWrite(12, HIGH);
  delay(1000);            
  digitalWrite(86, LOW); 
  delay(1000);              
}

For this example only the LED on pin 11 is blinking but in my big code I have pins 10 and 12 blinking too. I think that Arduino core should have a function to ignore wrong pin number to prevent strange behavior when user has wrong pin signed on code.

Best regards.

FernandoGarcia commented 7 years ago

A blink only with pin 11.

void setup() 
{
  pinMode(11, OUTPUT);
  pinMode(86, OUTPUT);
}

void loop() 
{
  digitalWrite(11, HIGH);
  delay(1000);            
  digitalWrite(86, LOW); 
  delay(1000);              
}
facchinm commented 7 years ago

Hi @FernandoGarcia , in fact using a pin number higher than the maximum "allowed" is not checked at all for a performance reason. The pin that gets selected depends on "random" bytes in the flash after the digital_pin_to_port_PGM array. What I don't understand is if you need a strict check or if you don't want side-effects. In the first case, digitalWrite(86, ... should do nothing, which is not what you need (I believe).

FernandoGarcia commented 7 years ago

Hi!

I don't want the side-effects when using a fake pin number.

In this case digitalWrite(86, ...); should be a null command without any effect over others pins but it doesn't happens on moment. I have the LED on pin 11 blinking with this code:

void loop() 
{
  digitalWrite(11, HIGH);
  delay(1000);            
  digitalWrite(86, LOW); 
  delay(1000);              
}

Best regards.

facchinm commented 7 years ago

Ok, so my question is: why are you writing digitalWrite(86, LOW); if it must have no effect :smile: ? Does it have any meaning (about the multiplexer you were talking about in the first post)?

FernandoGarcia commented 7 years ago

So I have 3 functions and only 2 free pins on Arduino to be used. In this case the user can select two functions useful to him so, don't need comment out the useless function when a fake pin is signed. The function will be checked but won't do anything.

My code is like this:

#ifdef USE_PCF8575
    PCF8575.digitalWrite(alimentadorPin, LOW);
#else
    digitalWrite(alimentadorPin, LOW);
#endif

If user has a PCF8575 connected the code will work with it. If user has it connected to an Arduino pin will work too. But if user don't want use this function can sign a fake pin number to alimentadorPin and this function won't act over any pin and won't be needed remove or comment out the code.

neu-rah commented 7 years ago

on the meanwhile you can do it by yourself... on file pins_arduino.h there is this define NUM_DIGITAL_PINS that might help you... my guess is that NUM_DIGITAL_PINS would be defined for every mcu, but that's just my guess. otherwise you can rule out abnormal pin numbers for each mcu because you already have that preprocessor directive filtering them. i would write alternative functions for pinMode/digitalRead/digitalWrite to do the filtering and use the alternatives on the code sketch, but of course this approach will only serve you in your sketches, it would be useless if you are doing a library.

Me too, I wish the pin mapping have been done otherwise... but it was not and now we can not change it without breaking compatibility.

Still there is some margin to change it, but its too narrow.

note: when i say we I do not express any official statement neither am I part of the official team.. I'm just another user like you.. and i can talk portuguese too ;)

facchinm commented 7 years ago

I agree, the control should be performed by the "wrapper" function using NUM_DIGITAL_PINS define; in this way, you can safely write something like

#ifdef USE_PCF8575
    PCF8575.digitalWrite(alimentadorPin, LOW);
#else 
#ifdef NUM_DIGITAL_PINS
    if (alimentadorPin < NUM_DIGITAL_PINS)
        digitalWrite(alimentadorPin, LOW);
    else
        //give some debug hints to the user or do nothing
#else
    digitalWrite(alimentadorPin, LOW);
#endif
#endif

Of course, that define doesn't take into account particular setups with "holes" in the numbering sequence or similar. I'd close the issue as "wontfix", feel free to reopen if I missed some points, thanks!

FernandoGarcia commented 7 years ago

Thanks for all suggestions but I don't think it's a particular issue of my code.

It's clearly a gap in Arduino core.

When the problem is in my code is more easy to find but if there any wrong pin defined in a library will be more hard to find the root of this strange behavior.

I hope you can reconsider your position.

FernandoGarcia commented 7 years ago

My solution for now are this custom functions:

void myPinMode(int pin, boolean mode)
{
  if ((pin >= 0) && (pin <= MAX_PIN_NUMBER))
  {
    pinMode(pin, mode);
  }
  else
  {

  }
}

void myDigitalWrite(int pin, boolean level)
{
  if ((pin >= 0) && (pin <= MAX_PIN_NUMBER))
  {
    digitalWrite(pin, level);
  }
  else
  {

  }
}

void myAnalogWrite(int pin, byte pwm)
{
  if ((pin >= 0) && (pin <= MAX_PIN_NUMBER))
  {
    analogWrite(pin, pwm);
  }
  else
  {

  }
}

int myAnalogRead(int pin)
{
  int value = 6666;

  if ((pin >= 0) && (pin <= MAX_PIN_NUMBER))
  {
    value = analogRead(pin);
  }
  else
  {

  }
  return value;
}