Combine two different programs and switch functionalities based on the input by sharing same pins

Hello, I have a rare requirement i.e.

  1. I have a sketch called Basic and another sketch called Advanced.
  2. In the basic sketch I am using few pins as I/O to trigger few relays and for different functionality.
  3. I have another sketch called Advanced, I am using the same pins as I/O for other functionality.
  4. Now I want to combine both programs as a single sketch and based on one digital pin the program should decide which functionality should execute.

In simple words, if pin2 is connected to GND pin then basic sketch functionality should execute and it pin 2 is open then Advanced sketch functionality should be used.

example basic sketch:

#include <avr/wdt.h> 

const int Relay1_PIN = 4;
const int Relay2_PIN = 5;

const int Relay3_PIN = 6;
const int Relay4_PIN = 7;

const int External_INPUT_PIN = 8;

const int Relay1_LED = 9;
const int Relay2_LED = 10;
const int Relay3_LED = 11;
const int Relay4_LED = 12;

const int BLINKLED = 13;

void setup() {
  pinMode(Relay1_PIN, OUTPUT);
  pinMode(Relay2_PIN, OUTPUT);
  pinMode(Relay3_PIN, OUTPUT);
  pinMode(Relay4_PIN, OUTPUT);
  
  pinMode(Relay1_LED, OUTPUT);
  pinMode(Relay2_LED, OUTPUT);
  pinMode(Relay3_LED, OUTPUT);
  pinMode(Relay4_LED, OUTPUT);
  
  pinMode(BLINKLED, OUTPUT);
  
  pinMode(External_INPUT_PIN, INPUT_PULLUP);

  digitalWrite(Relay1_PIN, HIGH);
  digitalWrite(Relay2_PIN, HIGH);
  digitalWrite(Relay3_PIN, HIGH);
  digitalWrite(Relay4_PIN, HIGH);
  
  digitalWrite(Relay1_LED, LOW);
  digitalWrite(Relay2_LED, LOW);
  digitalWrite(Relay3_LED, LOW);
  digitalWrite(Relay4_LED, LOW);
  digitalWrite(BLINKLED, LOW);
}

voild loop(){
 ## code to control relays ##
}

function mylogic()
{

}

Advanced sketch:
-------------------------
#include <avr/wdt.h> 

const int Relay5_PIN = 4;
const int Relay6_PIN = 5;
const int Relay7_PIN = 6;
const int Relay8_PIN = 7;

const int External_INPUT_PIN = 8;

const int Relay5_LED = 9;
const int Relay6_LED = 10;
const int Relay7_LED = 11;
const int Relay8_LED = 12;

const int BLINKLED = 13;

void setup() {
  pinMode(Relay5_PIN, OUTPUT);
  pinMode(Relay6_PIN, OUTPUT);
  pinMode(Relay7_PIN, OUTPUT);
  pinMode(Relay8_PIN, OUTPUT);
  
  pinMode(Relay5_LED, OUTPUT);
  pinMode(Relay6_LED, OUTPUT);
  pinMode(Relay7_LED, OUTPUT);
  pinMode(Relay8_LED, OUTPUT);
  
  pinMode(BLINKLED, OUTPUT);
  
  pinMode(External_INPUT_PIN, INPUT_PULLUP);

  digitalWrite(Relay5_PIN, HIGH);
  digitalWrite(Relay6_PIN, HIGH);
  digitalWrite(Relay7_PIN, HIGH);
  digitalWrite(Relay8_PIN, HIGH);
  
  digitalWrite(Relay5_LED, LOW);
  digitalWrite(Relay6_LED, LOW);
  digitalWrite(Relay7_LED, LOW);
  digitalWrite(Relay8_LED, LOW);
  digitalWrite(BLINKLED, LOW);
}

void loop(){
 ## code to control relays ##
 
 
}

function test(){

}

function two(){

}

I tried to club but not getting how to use same pins for different functionalities. Can anyone help me on this?

What is your problem?
Naturally you have a two different programs, switched by value of pin logic level. So if you need to use some pin as OUTPUT in the first code and INPUT in the second, you can add a two pinMode() statements in the setup:

void setup() {
 // choose between basic and advanced sketch
 selector = digitalRead(selectPin);

if (selector == LOW) {  // Basic code
 pinMode(Pin, OUTPUT);
}
else {    // Advanced
  pinMode(Pin, INPUT);
}
}

Do the same with every block of both codes

You want to run two relays with one pin, and two LEDs with one pin. You will need to ensure the correct current gets to the two devices (because parallel circuits "halve" the total current) and not exceed the 20mA limit per Arduino pin (or catastrophic failure of the Arduino) by using an externally powered device, usually a MOSFET, to act as a switch (controlled by Arduino pin) to allow high power through to the (multiple) devices.

I am looking for something like this....

void loop() {
 // choose between basic and advanced sketch
 selector = digitalRead(selectPin);

if (selector == LOW) {  // Basic code
  basicsketch();
}
else {    // Advanced
  Advancedsketch();
}
}

If you hope to just put the whole sketch into some function and then call it, it won't work.

yes it is not working. After lot of efforts still no luck

It can be done, but you need to redesign a both codes completely.

  • By now you should be aware we need to see schematics.

At a glance the setup() functions are identical.

With this

void loop() {
  pinMode(selectPin, INPUT_PULLUP);       // really just add this to the one setup
  int selector = digitalRead(selectPin);  // local. may be useful as a global variable IDK

  if (selector == LOW) {
    basic_loop();
  }
  else {
    advanced_loop();
  }
}

you run either original loop() function.

If your setup() functions differ, use the same pattern there, as you have been advised earlier, to select and execute one of the two original setup() functions.

a7

Each pin (regardless of sketch) is attached to two devices (relay AND LED). Depending on wiring, both devices could be energized at the same time, or one is off while the other is on, creating a possible current sink not good for the Arduino pin.

Are the setup() functions different? I see only cosmetic insignificant differences, the variable names.

I do not see a schematic, so it seems like pins 4 ... 7 are connected to relays or relay controllers, and pins 9 ... 12 are connected to LEDs.

That does rely on an interpretation of @chandu-mca06's variable names that may be invalid.

a7

// pin 4, 5, 6, 7 connected to...
// sketch 1 - relays 1, 2, 3, 4
const int Relay1_PIN = 4;
const int Relay2_PIN = 5;
const int Relay3_PIN = 6;
const int Relay4_PIN = 7;

// sketch 2 - relays 5, 6, 7, 8
const int Relay5_PIN = 4;
const int Relay6_PIN = 5;
const int Relay7_PIN = 6;
const int Relay8_PIN = 7;

// ==============================
// pin 9, 10, 11, 12 connected to...
// sketch 1 - LEDs 1, 2, 3, 4
const int Relay1_LED = 9;
const int Relay2_LED = 10;
const int Relay3_LED = 11;
const int Relay4_LED = 12;

// sketch 2 - LEDs 5, 6, 7, 8 
const int Relay5_LED = 9;
const int Relay6_LED = 10;
const int Relay7_LED = 11;
const int Relay8_LED = 12;

Setting pin 4 HIGH, sets Relay1 and Relay5 in whatever "HIGH" means to those relays.

Yes. Same with the LEDs. I just don't see what the problem is. There are no outputs wired together where one might be written HIGH whilst the other was LOW.

If there really are two LEDs, the only caveat would be that each have its own series current-limiting resistor and nor exceed the pin's current capability.

You could attach two different kinds of relay driver circuit, which might not work out so well, but if all these relays are like the cheap opto- or not isolated driver boards, again what would be the problem?

I don't see that this is meant to be wired up with two sets of LEDs and relays, only that they are named differently in the code.

@chandu-mca06 - perhaps we would all benefit from a larger description of why you are doing this and how the board will be used in different ways depending on the selector switch.

a7

No problem, code and devices will "work," but if this does not make it past Arduino-as-power-supply, two LEDs on one pin will glow dimmer (or asymmetrically) and sink twice the current... needing bigger/different sized resistors than the usual... and on the relay side, maybe one relay is actuated while the other chatters from not-high-enough-HIGH.

WWWD? (wokwi shows no imbalance)
(can't get into my wokwi... so just posting the sketch/diagram)

sketch.ino
byte relPin = 2;
byte ledPin = 3;

unsigned long relMillis, ledMillis, relTime = 500, ledTime = 100;

int ledPWM = 0, ledStep = 25, ledDir = 1;

void setup() {
  Serial.begin(115200);
  pinMode(relPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  relays();
  leds();
}

void relays() {
  if (millis() - relMillis > relTime) {
    relMillis = millis();
    digitalWrite(relPin, !digitalRead(relPin));
  }
}

void leds() {
  if (millis() - ledMillis > ledTime) {
    ledMillis = millis();
    ledPWM += ledStep * ledDir;
    if (ledPWM > 225 || ledPWM < 25)
      ledDir = -ledDir;
    analogWrite(ledPin, ledPWM);
    // printPWM(ledPWM);
  }
}

void printPWM(int pwm) {
  for (int i = 0; i < pwm / 25; i++)
    Serial.print(" ");
  Serial.print("* ");
  Serial.println(pwm);
}

diagram.json
{
  "version": 1,
  "author": "Anonymous maker",
  "editor": "wokwi",
  "parts": [
    { "type": "wokwi-arduino-nano", "id": "nano", "top": -4.8, "left": -0.5, "attrs": {} },
    {
      "type": "wokwi-led",
      "id": "led1",
      "top": -147.6,
      "left": 71,
      "attrs": { "color": "red", "flip": "" }
    },
    {
      "type": "wokwi-led",
      "id": "led2",
      "top": -147.6,
      "left": 90.6,
      "attrs": { "color": "red", "flip": "1" }
    },
    {
      "type": "wokwi-resistor",
      "id": "r1",
      "top": -62.4,
      "left": 66.65,
      "rotate": 90,
      "attrs": { "value": "330" }
    },
    {
      "type": "wokwi-resistor",
      "id": "r2",
      "top": -62.4,
      "left": 76.25,
      "rotate": 90,
      "attrs": { "value": "330" }
    },
    { "type": "wokwi-relay-module", "id": "relay1", "top": -124.6, "left": 163.2, "attrs": {} },
    { "type": "wokwi-relay-module", "id": "relay2", "top": -67, "left": 163.2, "attrs": {} }
  ],
  "connections": [
    [ "r1:1", "led1:A", "green", [ "h0" ] ],
    [ "r2:1", "led2:A", "green", [ "h0" ] ],
    [ "nano:3", "r1:2", "green", [ "v0" ] ],
    [ "nano:3", "r2:2", "green", [ "v0" ] ],
    [ "nano:GND.1", "led2:C", "black", [ "v-153.6", "h-28.4" ] ],
    [ "nano:GND.1", "led1:C", "black", [ "v-153.6", "h-58" ] ],
    [ "nano:GND.1", "relay2:GND", "black", [ "v0" ] ],
    [ "nano:GND.1", "relay1:GND", "black", [ "v0" ] ],
    [ "nano:5V", "relay2:VCC", "red", [ "v0" ] ],
    [ "nano:5V", "relay1:VCC", "red", [ "v0" ] ],
    [ "nano:2", "relay2:IN", "green", [ "v0" ] ],
    [ "nano:2", "relay1:IN", "green", [ "v0" ] ]
  ],
  "dependencies": {}
}

I am even thinking that possibility to use 74HC595 IC to expand the IO pins so that I can use different pins for both sketches so that same pi s will not share multiple devices at the same time.

Any thoughts on this?

  • As in post #8

By now you should be aware we need to see schematics.

Why not connect the LEDs (with appropriate resistors) to the same pins as the relay output pins? That would save 8 pins.

It's easier to use different controllers for each kit, and run every sketch on its own arduino.

A clone Arduino Nano costs about the same as the set of 74HC595 modules you need to share pins.

I can do that as i have multiple controllers however now the question is how to switch these controllers based on the input of digital pin of first controller

It's much easier than changing the code in the same arduino.

Share inputs for both controllers and run the code only if input is in defined state