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
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.
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
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
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).