ways to make 2 pins working simultaneously

Hello everybody
so i am in attempt to create a project which requires 2 pins to work {sometimes} simultaneously
and i wonder about available options i should use to make it happen
interrupts millis or anything else
description:
one pin has a push button which works as a toggle switch for a fan in a bathroom
second pin should turn on a servo motor which will go to certain angle stay there for one sec and go back to its origin angle. both codes and work
now since it is impossible to make both pins to work at the same time , i wont be able to turn on the servo as long as the fan works, or the other way around but i've heard there are ways around it like interrupts millis or
hw can i make it work?
Equipment Arduino nano

Thanks in Advance

Look at the following tutorials. I don't see a need to use interrupts.

BlinkWithoutDelay

Arduino Multiple Things

Several Things at a Time

Reading the subject title, I thought: "how many picoseconds between the pins are allowed".

There is a servo library: Servo - Arduino Reference.
It will make the servo signal for you, so you can do other things in the sketch.

When the function delay() is the problem, that can be fixed with millis(). However, a sketch with millis() has to be rewritten all over.

Can you show both sketches ?
You can start by investigating millis() with the Blink Without Delay page: https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay

button

int LEDState=0;
int LEDPin=8;
int buttonPin=5;
int buttonNew;
int buttonOld=1;
int dt=100;
 
void setup() {
  // 
Serial.begin(9600);
pinMode(LEDPin, OUTPUT);
pinMode(buttonPin, INPUT);
 
}
 
void loop() {
buttonNew=digitalRead(buttonPin);
if(buttonOld==0 && buttonNew==1){
  if (LEDState==0){
    digitalWrite(LEDPin,HIGH);
    LEDState=1;
  }
  else{
    digitalWrite(LEDPin, LOW);
    LEDState=0;
  }
}
buttonOld=buttonNew;
delay(dt);
}

servo

#include <Servo.h>

int posi = 50 ;       //position XXX changed so it attaches at the start point of sweep
int Servopin = 10 ;
int ServoDelay = 30 ;
Servo RedServo; //was coolServo XXXX

//these lines are new for the button cycle stuff
bool servoMustMove = false;
byte buttonPin = 3; //button from pin to ground

void setup()
{
  Serial.begin(9600);
  RedServo.write(posi); // XXX new so it attaches at the start point of sweep
  RedServo.attach(Servopin);
  pinMode(buttonPin, INPUT_PULLUP); //button from pin to ground
  Serial.println("setup done");
}

void loop()
{
  // the servo sweep stuff has been moved to a function servoSweep()
  if (!digitalRead(buttonPin)) servoMustMove = true; //! means not, this checks for button press
  if (servoMustMove) servoSweep();
}//loop

void servoSweep()
{
  for (posi = 50; posi <= 95; posi = posi + )  // angles ~ posotions  from 90 degrees to 50 degrees XXX lose the ;
  {
    //Serial.print("going up ");
    //Serial.println(posi);
    RedServo.write(posi);
    delay(ServoDelay);
  }
 
  delay(1500); //XXXX new, forgot it before
 
  for (posi = 95  ; posi >= 50; posi = posi - 2) // backwards  angles positions   from 50 back to 90 XXX lose the ;
  {
    //Serial.print("going down ");
    //Serial.println(posi);
    RedServo.write(posi);
    delay(ServoDelay);
  }

  servoMustMove = false; // XXXX new
}///

since it is impossible to make both pins to work at the same time , i wont be able to turn on the servo as long as the fan works

I can't imagine where you got that strange idea. Certainly false. No special logic is required either, you just turn them both on. There will only be a microseconds delay between the turn ons.

A slow servo motion can be done without delay(), by using millis() or a library.
I forgot which library is a good library :frowning:

In the Library Manager in the Arduino IDE is a "SlowMotionServo" library: GitHub - Locoduino/SlowMotionServo: SlowMotionServo is an Arduino library to drive servos slowly along a trajectory pos(t).
Can you have a look at it ?

When you use a library, then you have to ask the library if the servo has arrived at its new position. You also have to keep the library going by calling a 'update' function very often.
That is what you will see in the examples.

Reading a button with a small delay() to debounce it is possible. I use often 10ms delay for a small push button, but big knobs bounce a lot longer. The Bounce2 library can be used to debouce a button or a switch.

Both those library use millis().
You can also write everything from scratch with millis() yourself. After all, millis is fun :wink:

My tutorial How to code Timers and Delays in Arduino covers replacing delay() with millis() and introduces a simple library millisDelay the lets you start/stop/repeat delays.

There is a way to address a whole port in the arduino (at mega) at once. you can send data to all the pins on the same port (port a, b, etc...).
You can google to see some samples code.

abdelhmimas:
There is a way to address a whole port in the arduino (at mega) at once. you can send data to all the pins on the same port (port a, b, etc...).
You can google to see some samples code.

OP won't care about this. They have input on one pin, and output on the other.

Here's an example that might work for you (compiles, not tested). It breaks the problem into two different "tasks" each relying on millis timing and the servo using a state machine:

#include <Servo.h>

#define START_POS       50
#define STOP_POS        95

#define TIME_STEP       0
#define TIME_HOLD       1

//servo
int posi = START_POS;       //position XXX changed so it attaches at the start point of sweep

const uint8_t Servopin = 10;
const uint32_t ServoDelay = 30ul;
const uint32_t ServoHold = 1500ul;

Servo RedServo; //was coolServo XXXX

//these lines are new for the button cycle stuff
bool bServoMoving = false;
bool bDir;
uint8_t stateServo;
uint32_t timeServo;

const uint8_t servoButtonPin = 3; //button from pin to ground

//button
bool bLEDState=false;
const uint8_t LEDPin=8;
int buttonPin=5;
int buttonNew;
int buttonOld=1;

const uint32_t dt = 100ul;

uint32_t
    timeNow,
    timeButton=0;
 
void setup(void) 
{
    //
    Serial.begin(9600);
    pinMode(LEDPin, OUTPUT);
    pinMode(buttonPin, INPUT); 

    RedServo.write(posi); // XXX new so it attaches at the start point of sweep
    RedServo.attach(Servopin);
    pinMode(servoButtonPin, INPUT_PULLUP); //button from pin to ground
    Serial.println("setup done");
    
}//setup
 
void loop() 
{
    //button
    DoToggleButton();
    
    //servo
    DoServo();
    
}//loop

void DoToggleButton( void )
{
    timeNow = millis();
    if( timeNow - timeButton >= dt )
    {
        timeButton = timeNow;
            
        buttonNew = digitalRead( buttonPin );
        if( buttonOld == LOW && buttonNew == HIGH )
        {
            if( bLEDState == false )
            {
                digitalWrite(LEDPin,HIGH);
                bLEDState = true;
                
            }//if
            else
            {
                digitalWrite(LEDPin, LOW);
                bLEDState = false;
                
            }//else
            
        }//if
        
        buttonOld = buttonNew;

    }//if
    
}//DoToggleButton

void DoServo( void )
{
    timeNow = millis();
    
    switch( bServoMoving )
    {
        case    false:
            //servo not moving; is button pushed?
            if( digitalRead(buttonPin) == LOW ) 
            {
                bServoMoving = true;        //indicate servo moving
                posi = START_POS;           //init to start position
                bDir = true;                //true means counting 'up'
                stateServo = TIME_STEP;
                timeServo = timeNow;
                
            }//if
            
        break;

        case    true:
            switch( stateServo )
            {
                //servo is moving in this state
                case    TIME_STEP:
                    //time for a step?
                    if( timeNow - timeServo >= ServoDelay )
                    {
                        timeServo = timeNow;
                        //counting up?
                        if( bDir == true )
                        {
                            //bump position up by 1
                            posi++;
                            //if this step is the last...
                            if( posi == STOP_POS )
                            {
                                //set direction to count down
                                bDir = false;
                                //and set state to 1.5-sec hold
                                stateServo = TIME_HOLD;                                
                                
                            }//if
                            
                        }//if
                        else
                        {
                            //counting down; decrement position
                            posi--;
                            //if back at the start position...
                            if( posi == START_POS )
                            {
                                //set state machine back to "idle" state
                                bServoMoving = false;
                                    
                            }//if
                            
                        }//else

                        //move servo to latest position
                        RedServo.write(posi);                        
                        
                    }//if
                    
                break;

                case    TIME_HOLD:
                    //here we wait for 1.5-seconds
                    if( timeNow - timeServo >= ServoHold )
                    {
                        //when time is done, return to timing the steps
                        timeServo = timeNow;
                        //because we switched bDir to false, steps will count back to START_POS now
                        stateServo = TIME_STEP;
                        
                    }//if
                    
                break;
                                
            }//switch
            
        break;
        
    }//switch
    
}//DoServo

aarg:
OP won't care about this. They have input on one pin, and output on the other.

Not sure this is true, I understood from the post OP was talking about two outputs, otherwise this whole post doesn’t make any sense.
Usually, when we talk about turning on two pins at the same time, it is obvious that these are outputs.

abdelhmimas:
otherwise this whole post doesn’t make any sense

You nailed it :smiley_cat:
The question is about doing multiple code-things at the same time. The question is not about output pins. A sketch with millis() is the solution. That's all. The solutions are already provided, either with libraries (I mentioned two libraries) or from scratch (see example by Blackfin).

Empty imported post

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.