Countdown once event is triggered - arduino

I'm just getting started with my Arduino and I want to operate a relay for a certain amount of time once I press a contact switch, but still be able to stop the it again at any time by pressing the button again. I've got the press the button to start and stop working Ok, but can't get the timer bit to work at all. Below is what I've got working so far.
TIA.
void setup()
{
Serial.begin(9600);
pinMode(7, INPUT);
pinMode(6, INPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
}
void loop()
{
Serial.print("Pin 7 ");
Serial.println(digitalRead(7));
if (digitalRead(6) == LOW && digitalRead(7) == HIGH) {
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
delay(250); // Wait for 250 millisecond(s)
}
if (digitalRead(6) == HIGH && digitalRead(7) == HIGH) {
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
delay(250); // Wait for 250 millisecond(s)
}
}

bool buttonState = 0, buttonStateBefore = 0;
bool toggle = 0;
unsigned long timeNow = 0;
buttonState = digitalRead(buttonPin);
if(buttonState > buttonStateBefore) {
toggle = !toogle; // negates the toogle
timeNow = millis(); // milliseconds to the time you press the button
}
buttonStateBefore = buttonState;
if(toggle && millis() < timeNow + delayTime) {
// relay on
}
else {
// relay off
}
Explanation:
When you press the button, buttonState beign now one, is bigger than the buttonStateBefore. So the if-statement is true. The variable toggle is now true and the time is set to the amount of milliseconds after starting the arduino. After the first if the buttonStateBefore is set to be the buttonState, to not toggle the toggle variable every circle. The second if-statement checks if the toggle variable is true and if the time has not exceeded. If one of the two things is not the case, the relay is turned off.
I hope this is helpful.
P.s. You can shorten your code if you use a for-loop for the digitalWrite
for(int i = 3; i < 7; i++) {
digitalWrite(i, true);
}

Related

Disable push button for 30 sec after press arduino

I am working with Arduino as I am new need your help please Thanks!
I am turning on the LED light via push-button for 30 seconds all working fine but there is one issue after pushing the button light on start from 0 sec but if I push the button after 15 sec it will start again from 0 sec so, is there any way can I disable the push button also for 30 sec so it will run only 30 sec even I will push the button and button will work only when the light of after 30 sec.
int BUTTON = 2;
int BUTTONstate = 0;
int LED = 8;
void setup() {
pinMode(BUTTON, INPUT);
pinMode(LED, OUTPUT);
}
void loop() {
static unsigned long startTime = 0;
BUTTONstate = digitalRead(BUTTON);
if (BUTTONstate == HIGH){
if (millis() - startTime >= 30000)
digitalWrite(LED, LOW);
}
else{
digitalWrite(LED, HIGH);
startTime = millis();
}
}
I got the correct code working fine:
int pin1 = 13;
int LED = 8;
void setup()
{
pinMode(pin1, INPUT_PULLUP);
pinMode(LED, OUTPUT);
}
long offAt = 0;
void loop()
{
if ((digitalRead(LED) == LOW ) && (digitalRead(pin1) == LOW) ) //if LED is off and button is pressed [low because it has pullup resistor]
{
digitalWrite(LED, HIGH);
offAt = millis() + 30000; //store var of now + 5 seconds
}
if (digitalRead(LED) == HIGH) //if led is on
{
if (millis() >= offAt) //see if it's time to turn off LED
{
digitalWrite(LED, LOW); //it's time. this also re-enables the button
}
}
}

running two LEDs with two buttons

I am new to Arduino programing. I am trying to get two buttons to light two LEDs like so. press button1 turn on light 1 turn off light 2, button2 turn on light 1 and 2. like indicators for speed selection.
this is the code I have so far.
const int BUTTON1 = 2;
const int BUTTON2 = 3;
const int LED1 = 9;
const int LED2 = 10;
int BUTTONstate1 = 0;
int BUTTONstate2 = 0;
void setup()
{
pinMode(BUTTON1, INPUT);
pinMode(BUTTON2, INPUT);
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
}
void loop(1)
{
BUTTONstate1 = digitalRead(BUTTON1);
if (BUTTONstate1 == HIGH);
digitalWrite(LED1, HIGH);
digitalwrite(LED2, low);
}
void loop(2)
{
BUTTONstate2 = digitalRead(BUTTON2);
if (BUTTONstate2 == HIGH)
digitalWrite(LED1, HIGH);
digitalwrite(led2, HIGH);
}
when i run the code I get ERROR 19:10 error: variable or field 'loop' declared void. it is the line after void loop(1) and void loop(2).
void loop(1) and void loop(2) don't make sense.
You only implement void loop() and handle both buttons in that function.
Arduino will call loop() in an infinite loop over and over. Having two loop functions doesn't make sense and causes compiler errors.
If you want to have that functionality in two different functiosn implement them using different names and call both of them inside loop()
I've never seen someone uses two void loops at one time. You have to use only one void loop(). Here is an example:
void loop() {
BUTTONstate1 = digitalRead(BUTTON1);
BUTTONstate2 = digitalRead(BUTTON2);
if (BUTTONstate1 == HIGH) {
digitalWrite(LED1, HIGH);
digitalwrite(LED2, LOW);
}
if (BUTTONstate2 == HIGH) {
digitalWrite(LED1, HIGH);
digitalwrite(LED2, HIGH);
}
}
You also make another error here. Don't ever print ; after if()

How can I set a ceratin time interval for reading input in my Arduino game?

I'm making a game with my Arduino Uno.
4 leds on the breadboards are displaying a random binary number.
The player needs to press the button to put in the number that he sees
(for example, if the leds are 0011, push the button 3 times).
If he guessed right, he wins (another led blinks). If not, he loses (led turns on and stays on).
But I want the player to automatically lose if he hasn't pressed a button for two seconds.
But I'm really a beginner so bear with me. Below I'll post what I've got so far. But it's not exactly working. When I turn it on, without me pressing the button, it just goes straight to "you win" and the next round. What am I doing wrong?
int led1 = 9;
int led2 = 6;
int led3 = 5;
int led4 = 3;
int ledResult = 13; //will blink when you won, stay on when you lost
int buttonPin = 2;
int val = 0; // variable for reading the pin status
int buttonPushCounter = 0;
int buttonState = 0;
int lastButtonState = 0;
long interval = 2000;
long randomNumber;
void setup() {
Serial.begin(9600); //starts serial communication
pinMode (led1, OUTPUT);
pinMode (led2, OUTPUT);
pinMode (led3, OUTPUT);
pinMode (led4, OUTPUT);
pinMode (ledResult, OUTPUT);
pinMode (buttonPin, INPUT);
randomSeed(analogRead(A0)); //the pin is unconnected so it'll return something random (0-1023)
}
void loop() {
randomNumber = random(1, 16);
Serial.println("Random Numbers sequence"); //just for self-check
Serial.println(randomNumber);
if (randomNumber >= 8)
{
digitalWrite (led1, HIGH);
randomNumber - 8;
}
else
{
digitalWrite (led1, LOW);
}
if (randomNumber >= 4)
{
digitalWrite (led2, HIGH);
randomNumber - 4;
}
else
{
digitalWrite (led3, LOW);
}
if (randomNumber >= 2)
{
digitalWrite (led4, HIGH);
randomNumber - 2;
}
else
{
digitalWrite (led1, LOW);
}
if (randomNumber = 1)
{
digitalWrite (led2, HIGH);
}
else
{
digitalWrite (led1, LOW);
}
unsigned long currentMillis = millis();
if (currentMillis > interval) {
Serial.println("You lost.");
digitalWrite(ledResult, HIGH);
}else{
//READ BUTTON STATE
buttonState = digitalRead(buttonPin);
// compare the buttonState to its previous state
if (buttonState != lastButtonState) {
if (buttonState == HIGH)
{
buttonPushCounter++;
Serial.println("Button push counter:");
Serial.println(buttonPushCounter);
}
// Delay a little bit to avoid bouncing
delay(50);
}
// save the current state as the last state, for next time through the loop
lastButtonState = buttonState;
if (buttonPushCounter = randomNumber) {
Serial.println("You won!");
digitalWrite(ledResult, HIGH);
delay(700);
digitalWrite(ledResult, LOW);
delay(700);
}
else
{
Serial.println("You lost.");
digitalWrite(ledResult, HIGH);
}
}
}
Essentially you'll want to have a main loop that probes/polls for user input, and if there's no input from the user on probe, then check the current millis time against when you called it for start. This will give you the elapsed time since no input was detected. If the elapsed time is greater than your threshold, you break out of the loop and check a timeout flag to see if you proceed with the button validation code or branch to the "lose" code.
Without writing the whole thing, here's a C pseudo-code mock up of the idea (commented to explain):
void loop() {
while (is_running) { // main loop
unsigned long start = millis(); // get starting probe time
bool timeout = false;
while ((buttonState = probe_input()) == no_input_val) {
/* probe_input function returned no input,
so check for timeout. If the probe_input function
did return a 'value', then this loop won't iterate
and you can check the buttonState below */
if ((millis() - start) >= interval) {
/* millis is monotonic time, so calling it, then
subtracting the value from the start value will give
us elapsed time since user did not give input. */
timeout = true;
break;
}
}
if (!timeout) {
/* button state/level code */
} else {
// lose code
}
}
}
Again, this is just pseudo-code and won't compile as you'd need to implement the probe_input function to poll for input, but it's more to illustrate what you'd need to do to get you moving in the direction you're wanting.
I hope that can help.

Arduino Code LED failure to alternate

Traffic light just stays on red rather than alternating.
Wanted it to stay on for 10s then off for 10s, continuing ad infinitum.
Dont want to use the delay function cos need to do other stuff while the LED continues to alternate.
Thanks
int red = 10; // red traffic light LED on pin 10
int redcounter;
// the setup routine runs once when you press reset:
void setup()
{
// initialize the digital pin as an output.
pinMode(red, OUTPUT);
digitalWrite(red, LOW);
redcounter = 0;
}
// the loop routine runs over and over again forever:
void loop()
{
redcounter = redcounter +1;
if(redcounter==1000)
{
redcounter=0;
if(digitalRead(red)==HIGH)
{
digitalWrite(red, LOW);
}
if(digitalRead(red)==LOW)
{
digitalWrite(red, HIGH);
}
}
You try to read a port which is configured as an OUTPUT. I don't know if this is supposed to work, but it would be more clear if you simply use another port as INPUT and feedback the signal you want to check in that port. I'm not sure however if it makes much sense to check the state of a signal you generate yourself (?). Moreover your redcounter is just "Active waiting", and arduino provides a delay function which does exactly that.
int red=10;
int signal=11;
void setup()
{
pinMode(red, OUTPUT);
pinMode(signal, INPUT);
digitalWrite(red, LOW);
}
void loop()
{
delay(1000);
if(digitalRead(signal)==HIGH)
{
digitalWrite(red, LOW);
}
if(digitalRead(signal)==LOW)
{
digitalWrite(red, HIGH);
}
}
Use elseif instead of if here:
if(digitalRead(red)==HIGH)
{
digitalWrite(red, LOW);
}
else if(digitalRead(red)==LOW)
{
digitalWrite(red, HIGH);
}
In your old solution every time red turned low, it was turned high a moment later.
Two issues in your code are that digitalread will not read an output pin and if you use an increment counter you won't be able to accurately denote time. Sorry if I missed a bracket or something I was doing this on the mobile app.
Use this:
int red = 10; // red traffic light LED on pin 10
int redcounter;
boolean pinState = false;
int delayTime = 10000;
// the setup routine runs once when you press reset:
void setup() {
// initialize the digital pin as an output.
pinMode(red, OUTPUT);
digitalWrite(red, LOW);
redcounter = millis();
}
// the loop routine runs over and over again forever:
void loop() {
if((millis() - red counter) > delayTime) {
redcounter=millis();
if(pinState) {
digitalWrite(red, LOW);
pinState = false;
}
else {
digitalWrite(red, HIGH);
pinState = true;
}
}
}

Arduino, if else LED "stuck"

So the code is not working properply, there are two leds that wont turn off "highliten" the problem. when i run the Else part of the program. i want to turn them off in the else part. :)
include
byte ledPin[] = {8, 9, 10, 11, 12, 13}; //--------------------------------.
int ledDelay; // Del 1
int direction = 1;
int currentLED = 0;
unsigned long changeTime;
int potPin = 0;
Servo myservo; // create servo object to control a servo
int potpin = 0; // analog pin used to connect the potentiometer
int val; // variable to read the value from the analog pin
int va;
void setup()
{
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, INPUT);
myservo.attach(3); // attaches the servo on pin 9 to the servo object
Serial.begin(9600);
for (int x=0; x<6; x++) {
pinMode(ledPin[x], OUTPUT); }
changeTime = millis();
}
void loop() {
int on = digitalRead(6);
if (on == HIGH)
{
myservo.attach(3);
// Here is the problem!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if va < 523)
{
digitalWrite(5, HIGH);
}
else if (va > 555)
{
digitalWrite(4, HIGH);
}
else
{
digitalWrite(4, LOW);
digitalWrite(5, LOW);
}
// Here is the problem!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
digitalWrite(12, LOW);
digitalWrite(13, LOW);
va = analogRead(potPin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(va, 0, 1023, 0, 179); // scale it to use it with the servo (value between 0 and 180)
myservo.write(val); // sets the servo position according to the scaled value
delay(1); // waits for the servo to get there
}
else
{
myservo.detach();
digitalWrite(5, LOW);
digitalWrite(4, LOW);
ledDelay = analogRead(potPin) / 4;
if ((millis() - changeTime) > ledDelay)
{
changeLED();
changeTime = millis();
}
}
}
void changeLED() {
for (int x=0; x<6; x++)
{
digitalWrite(ledPin[x], LOW);
}
digitalWrite(ledPin[currentLED], HIGH);
currentLED += direction;
if (currentLED == 6) {direction = -1;}
if (currentLED == 0) {direction = 1;}
}
in advance Thank you!
Right at the end of the sketch you have the following line:
if (currentLED == 6) { direction = -1; }
I think, without actually running the program, that the problem is here. In the previous line you have added one to the value of currentLED and you are checking to see if you have gone off the end of the ledPin array. You change the direction but you don't reset the currentLED position to be back inside the ledPin range.
The next time changeLED is called it tries to call digitalWrite(ledPin[currentLED], HIGH); but the value of currentLED is 6, which is outside the ledPin array. The Arduino probably gets upset at this point.
I think you simply need to change the statement to check whether currentLED == 5 rather than 6. This will mean that next time that changeLED is called the last LED will be turned on and the value of currentLED will be decremented (direction == -1), keeping it inside the ledPin range.

Resources