Can't do nested functions,what's a way around that? [duplicate] - c++

This question already has answers here:
What are forward declarations in C++?
(8 answers)
Closed 5 years ago.
Im working with Arduino IDE, which doesn't allow nested functions, or calling a function before it had been declared(it doesnt jump to find it)..
In my code, I need either one or the other..
Also, making it all one big function does not work because when i check back to an earlier sensor, i have to write what to do if yes and if no over and over forever.
Here, im trying to sense light, if theres light, go to the PIR sensor, if not, run light sensor again. now if the PIR senses motion twice in 3.5 sec, check color, if not, check light.
Now the color senses color and clasifies it(r g or b). now it checks for PIR again and if there's movement, it check color again and checks pir again. now if the pir doesnt sense movement, it sends to the lines to serial..
I declared some functions before I used them(print lines) but some of them not because i get stuck in a loop.
When i check light, if its positive, i run the PIR,so i would need to declare the pir function before ligth. but in the pir, if its negative(no movement), i run light sensor, implying that i should declare light sensor before pir.
Im stuck in that loop...
int lightPin = A0;
int valLight = 0;
int ledTrans = 2;
int pirTrans = 3;
int pirPin = 4;
int pirState = LOW;
int CalTime = 30;
int colorTrans = 5;
int s2 = 6;
int s3 = 7;
int OUTpin= 8;
boolean RD= false;
boolean GD = false ;
boolean BD = false;
int rfPin = 9;
void setup() {
pinMode(A0,INPUT);
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
pinMode(4,INPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(7,OUTPUT);
pinMode(8,INPUT);
pinMode(9,OUTPUT);
Serial.begin(9600);
}
void printlines();
void pirSensor();
void colorSensor();
void pirSensor2();
void lightSensor() {
//light sensor
valLight = analogRead(A0);
delay(1000);
if (valLight >= 300) {
ledTrans = HIGH;
pirTrans = HIGH;
pirSensor();
} else {
delay(8000);
}
}
void pirSensor() {
// Calibration
for ( byte i = 0; i < 30; i++) {
delay(1000);
}
// Check PIR state
int pirState = digitalRead(2);
delay(1500);
pirState = digitalRead(2);
if (pirState == HIGH) {
colorTrans = HIGH;
colorSensor();
} else if (pirState == LOW) {
pirState = LOW;
lightSensor();
}
}
void colorSensor(){
//Check Color reads pulse for RGB
// void checkred
digitalWrite(s2, LOW);
digitalWrite(s3, LOW);
unsigned int RW = 255 - (pulseIn(OUTpin, LOW)/ 400 - 1); // turns into 0-255
delay(6000);
// void checkgreen
digitalWrite(s2,LOW);
digitalWrite(s3,HIGH);
unsigned int GW = 255 - (pulseIn(OUTpin, LOW)/ 400 - 1);
delay(6000);
// void checkblue
digitalWrite(s2, HIGH);
digitalWrite( s3, HIGH);
unsigned int BW = 255 - (pulseIn(OUTpin, LOW) / 400 - 1);
delay(6000);
// seeing which color I got(r g or b)
if (RW > BW && RW > GW){
RD = true;
delay(7000);
} else if (GW > RW && GW > BW){
GD = true;
delay(7000);
} else if (BW > RW && BW > GW){
BD = true;
delay(4000);
}
}
void pirSensor2(){
pirState = digitalRead(2);
delay(1500);
pirState = digitalRead(2);
if(pirState = HIGH){
colorSensor();
}else{
printlines();
}
}
void printlines(){
if(RD){
Serial.print("RED DETECTED");
} else if(GD){
Serial.print("GREEN DETECTED");
}else if(BD){
Serial.print("BLUE DETECTED");
}else if(RD && GD){
Serial.print("RED & GREEN DETECTED");
}else if(RD && BD){
Serial.print("RED & BLUE DETECTED");
}else if(BD && GD){
Serial.print("GREEN & BLUE DETECTED");
}else if(RD && GD && BD){
Serial.print("RED, GREEN, BLUE DETECTED");
}
delay(7000);
}

You can declare a function before you define it:
void setup();
Then you can call it:
setup();
...and somewhere later in the file you can write its definition:
void setup() {
// implementation here
}

Related

Why the GSM Module data signal makes the PIR Motion sensor value to HIGH Arduino

I was creating a PIR Motion sensor and GSM Module SMS 800A based Security System with Arduino UNO
But I am facing a problem from 2 to 3 days that whenever I send a SMS from my phone to my GSM module then the Motion sensor automatically detects a motion and makes the system active.
Please tell me why is this happening?
This is my code :->
#include <SoftwareSerial.h>
#include <Sim800L.h>
#include <MemoryFree.h>
Sim800L GSM(10, 11);
SoftwareSerial sim800(10, 11); //2 is TX and 3 is RX
int day, month, year, minute, second, hour;
int onDay, onMonth, onYear, onMinute, onSecond, onHour;
int offDay, offMonth, offYear, offMinute, offSecond, offHour;
unsigned long prevMillis;
unsigned long currentMillis;
const long interval = 30000;
boolean timeStatus = false;
int RTCPerm;
int led = 13;
int pin = 5;
int x = 1;
int m = 0;
char y;
char t;
int value = 0;
int pirState = LOW;
char n[3];
int j = 0;
int i = 0;
char data[200] = {};
int condition = 0;
char DTMF[200] = {};
int z;
int delayOnMinute, delayOffMinute, delayOnHour, delayOffHour;
// connections
//
// GSM ARDUINO UNO
//
// GND -----> GND
// TX -----> 2
// RX -----> 3
// Power Supply -----> 12V 1A or 5V 2A
//
// Motion Sensor Arduino UNO
//
// VCC -----> 5V
// GND -----> GND
// OUT -----> 4
void setup() {
pinMode(led, OUTPUT);
pinMode(12, OUTPUT);
pinMode(pin, INPUT);
Serial.begin(9600);
sim800.begin(9600);
delay(6000);
sim800.println(F("AT+CMGF=1"));
sim800.println(F("AT+CNMI=2, 2, 0, 0, 0"));
sim800.println(F("AT+DDET=1"));
GSM.begin(9600); // for RTC data input
delay(5000);
onMinute = 30;
onHour = 17;
offMinute = 00;
offHour = 15;
}
void loop() {
while (RTCPerm == 0) {
RTCStatus();
prevMillis = millis();
while (currentMillis - prevMillis != interval) {
// save the last time you blinked the LED
currentMillis = millis();
SMSRecieve();
if (timeStatus == true) {
value = digitalRead(pin);
if (value == HIGH) {
digitalWrite(led, HIGH);
if (pirState == LOW) {
goto Motion;
}
}
}
}
}
Serial.println("Hello");
value = digitalRead(pin);
if (value == HIGH) {
digitalWrite(led, HIGH);
if (pirState == LOW) {
Motion:
Serial.println(F("Motion Detected!"));
sim800.begin(9600);
So in the loop function you can see the SMS Receive function that checks whether there is any incoming SMS or not. So whenever I send a SMS to my GSM then my Motion sensor gets active and goes to label Motion which activates other functioning like starting the alarm etc.
This is the code of SMSRecieve() Function :->
void SMSRecieve() {
Samarth:
/* if (condition == 2) {
memset(data, 0, sizeof(data));
y = 0;
condition = 1;
}*/
if (sim800.available())
{ // Printing the collected data
y = sim800.read();
Serial.write(y);
if (y == '#') {
goto skip;
}
data[i] = y;
i++;
skip:
if (strstr(data, "off") || strstr(data, "OFF") || strstr(data, "Off")) {
// Do Something
} else if (strstr(data, "Lighton") || strstr(data, "lighton") || strstr(data, "LightOn") || strstr(data, "LIGHTON")) {
// Do Something
}else if (strstr(data, "Lightoff") || strstr(data, "lightoff") || strstr(data, "LightOff") || strstr(data, "LIGHTOFF")) {
// Do Something
}
}
}
Please help me where I am doing wrong ?
After testing the situation again and again I got the solution and the reason why that was happening.
REASON:- PIR Motion Sensors also detect the RF and other unseen frequencies in the air. So whenever I sent a SMS to my GSM, it was detected by my PIR Motion Sensor.
SOLUTION:- The GSM Module should be kept with at least 2 feet of distance from the PIR Motion Sensor

How can I call three different functions based on if my button was A) just pressed, B) being held Down and C) Just released?

I'm writing an Arduino program to control a minigun for a friend's cosplay. I need to write a program that when the button is pressed the motor ramps up from 0 to a given value (for now lets say "analogWrite(output_pin,200);") then loop at that RPM until the button is released, at which point it needs to ramp down back to zero.
When I try to put ramping into a loop it doesn't finish the code. I
I need something like this in c++ code for the Arduino button. (I've tried similar things using the "delay" function to no avail)
motorspeed = 0
if buttonpress == True:
buttonheld = True
for i in range (0,10):
delay(1)
motorspeed =+ 20
if buttonpress == False:
motorspeed = 0
if buttonheld == True:
motorspeed = 200
if buttonpress == False:
for i in range(0,10):
delay(1)
motorspeed =- 20
else:
#shut off motor
#Play error sound
Here is the current code that only runs the motor at one speed when the button is held down.
const int button1 =4;
int BUTTONstate1 = 0;
void setup()
{
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(9, OUTPUT);
pinMode(button1, INPUT);
}
void loop()
{
//set button to read
BUTTONstate1 = digitalRead(button1);
//if button is pressed
if (BUTTONstate1 == HIGH)
{
//run current through motor
digitalWrite(2, LOW);
digitalWrite(3, HIGH);
//set speed
//Rampup
analogWrite(9,200);
}
else
{
digitalWrite(2, LOW);
digitalWrite(3, LOW);
}
}
Here is a virtual environment for the circuit
https://www.tinkercad.com/things/cLOBc9JJuTz-copy-of-dayloncircuitrefinecode/editel?sharecode=b6cqTLlNqUCCN09-mQ_zykp5sMnXx6KLt_KNqlXJmcs
I would recommend using interrupts, it's pretty well documented in Arduino reference:
Arduino reference - Interrupts
Most helpful is "Parameters" and "Example code" section. I think you should prepare two methods and attach interrupt to your input (button) pin on RISING and FALLING trigger.
Make sure that the button pin can be used for interrupt (on Arduino UNO / NANO only pin 2 and 3).
I think it should look similar to this (I haven't tested that):
#define buttonPin 2; // pin usable for interrupt
#define outputPin 9;
#define powerPinA 3;
#define powerPinB 4;
bool running = false;
int currentSpeed = 0;
void buttonUp()
{
digitalWrite(powerPinA, LOW);
digitalWrite(powerPinB, LOW);
running = false;
}
void buttonDown()
{
digitalWrite(powerPinA, LOW);
digitalWrite(powerPinB, HIGH);
running = true;
}
void setup()
{
pinMode(outputPin, OUTPUT);
pinMode(powerPinA, OUTPUT);
pinMode(powerPinB, OUTPUT);
pinMode(buttonPin, INPUT);
attachInterrupt(digitalPinToInterrupt(interruptPin), buttonUp, RAISING);
attachInterrupt(digitalPinToInterrupt(interruptPin), buttonDown, FALLING);
}
void loop()
{
delay(1);
if (running && currentSpeed < 200)
currentSpeed += 20;
else if (!running && currentSpeed > 0)
currentSpeed -= 20;
analogWrite(outputPin, currentSpeed);
}
Here's an example that doesn't rely on any interrupts. Just reading the button and remembering the state in a variable and remembering the time of the last step in a variable to check against millis() (Compiled but Untested)
int buttonPin = 5;
int lastButtonState = HIGH;
unsigned long lastRampStep;
unsigned int stepTime = 10; // 10ms steps. Set to whatever you want.
int analogPin = 3;
int analogLevel = 0;
int maxLevel = 200;
int analogStepSize = 10;
void setup() {
pinMode(buttonPin, INPUT_PULLUP); // will read LOW when pressed
}
void loop() {
int buttonState = digitalRead(buttonPin);
if (buttonState != lastButtonState) {
// The button just changed!
if (buttonState == LOW) {
// was just now pressed
analogLevel = 0; // start ramp up
lastRampStep = millis(); // note the time that we took this step
} else {
// Button just released.
// not sure what you want to happen here
}
}
else if (buttonState == LOW) {
// While button is held ramp until we reach the max level
if(analogLevel < maxLevel){
if(millis() - lastRampStep >= stepTime){
analogLevel += analogStepSize;
lastRampStep = millis();
}
}
} else {
// While button is released (HIGH) ramp back down:
if(analogLevel > 0){
if(millis() - lastRampStep >= stepTime){
analogLevel -= analogStepSize;
lastRampStep = millis();
}
}
}
analogWrite(analogPin, analogLevel);
lastButtonState = buttonState;
}
You could use interrupts to handle pressed/release, set a value, and handle the ramp up/down in the loop.
Keep in mind that you should also debounce the button.
Below is some pseudocode:
const byte maxLevel = 200; // some example values (max 255)
const int rampDelay = 5;
volatile byte targetLevel = 0;
byte currentLevel = 0;
// ...
ISR for Button { // Could be in one ore two ISR's
if pressed
targetLevel = maxLevel;
// possible other calls
if released
targetLevel = 0;
// possible other calls
}
void loop()
{
if (currentLevel < targetLevel) {
SetLevel(++currentLevel);
}
else if (currentLevel > targetLevel) {
SetLevel(--currentLevel);
}
// if currentLevel == targetLevel nothing changes
// if your device is battery powered you could even put the mcu
// to sleep when both levels are zero (and wake up from the ISR)
// no need for constantly polling the button when using ISR
delay(rampDelay);
}
This will also start ramping down immediately if the button is released before the motor is at full speed.

Use 2 leds and 2 buttons using arduino and processing

I’m kind of stuck on something. I am trying to work 2 leds using arduino with 2 buttons in processing. The goal is to link 1 button to one led.
Now the problem. I have tried several things, but i cannot get the second led to work. The first led is working on both buttons in processing.
Can someone help me to figure out what i did wrong?
ARDUINO CODE
int LED1 = 10;
int LED2 = 11;
int val1 = 0;
int val2 = 0;
void setup() {
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
Serial.begin(9600);
}
void loop() {
analogWrite(LED1, LOW);
analogWrite(LED2, LOW);
if (Serial.available() >1){
val1 = Serial.read();
val2 = Serial.read();
}
if (val1 >10 && val2 ==0){
digitalWrite(LED1, HIGH);
}else{
digitalWrite(LED1, LOW);
}
if (val2 >10 && val1 ==0){
digitalWrite(LED2, HIGH);
}else{
digitalWrite(LED2, LOW);
}
}
PROCESSING CODE
import processing.serial.*;
Serial myPort;
void setup() {
size(640, 360);
background(100);
noStroke();
String portName = Serial.list() [1];
myPort = new Serial(this, portName, 9600);
}
int value1 = 0;
int value2 = 0;
void draw() {
if (myPort.available()>0){
}
fill(value1);
rect(150, 50, 50, 50);
fill(value2);
rect(50, 210, 50, 50);
println("VALUE1_"+value1);
println("VALUE2_"+value2);
}
void mousePressed() {
if (mouseX > 149 && mouseX < 200 && mouseY > 49 && mouseY < 101) {
if (value1 == 0){
value1 = 255;
myPort.write(value1);
}else{
value1 = 0;
myPort.write(value1);
}
}
if (mouseX > 49 && mouseX < 100 && mouseY > 209 && mouseY < 250) {
if (value2 == 0){
value2 = 255;
myPort.write(value2);
}else {
value2 = 0;
myPort.write(value2);
}
}
}
First things first. Design your system! What's the smart way of communication? Sending so many bytes? or just one byte? If I am to do it, I would think of 4 different possible states : 1- Both LEDs should be on -> I would send A to Arduino to indicate this state 2- Left LED is on, while right LED is off -> send B to Arduino 3- Right LED is on, while left LED is off -> send C to Arduino 4- Both LEDs are off -> send D to Arduino
Now your processing code can be something like this:
import processing.serial.*;
Serial myPort;
boolean leftLed;
boolean rightLed;
void setup() {
size(640, 360);
background(100);
noStroke();
String portName = Serial.list() [1];
myPort = new Serial(this, portName, 9600);
leftLed=false;
rightLed=false;
}
void draw() {
fill(value1);
rect(150, 50, 50, 50);
fill(value2);
rect(50, 210, 50, 50);
}
void updateArduino(){
if(rightLed && leftLed) myPort.write("A");
else if(leftLed) myPort.write("B");
else if(rightLed) myPort.write("C");
else myPort.write("D");
}
void mousePressed() {
if (mouseX > 149 && mouseX < 200 && mouseY > 49 && mouseY < 101)
leftLed = !leftLed;
else if (mouseX > 49 && mouseX < 100 && mouseY > 209 && mouseY < 250)
rightLed=!rightLed;
updateArduino();
}
And in Arduino, read them like this:
if (Serial.available()){
char temp=Serial.read();
if(temp=='A') {
//turn on both lights
}
else if(temp=='B'){
//turn on left light
}
else if(temp=='C'){
//turn on right light
}
else if(temp=='D'){
//turn off both lights
}
}

How can I blink a LED differently when I press a toggle button?

I'm trying to blink a LED according to press of toggle button. If I press the first toggle switch the first time, LED blinks at 5 Hz, when I press the toggle button for the second time, LED blink at 6 Hz and when I press the third time, LED turns off.
I tried using the program below, but It's not working as I wanted.
// constants won't change. They're used here to set pin numbers:
const int buttonPin = 7; // the number of the pushbutton pin
const int ledPin = 6; // the number of the LED pin
// variables will change:
int buttonState = 0;
// variable for reading the pushbutton status
void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
Serial.begin(9600);
}
void loop() {
int x=0;
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
Serial.print(x);
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (buttonState == HIGH && x==0) {
// turn LED on:
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
Serial.print(x);
} else {
// turn LED off:
x = x+1;
}
if (buttonState == HIGH && x==1) {
// turn LED on:
digitalWrite(ledPin, HIGH);
delay(2000);
digitalWrite(ledPin, LOW);
delay(2000);
Serial.print(x);
} else {
// turn LED off:
digitalWrite(ledPin, LOW);
x = x+1;
}
if (buttonState == HIGH && x==2) {
// turn LED on:
digitalWrite(ledPin, HIGH);
delay(3000);
digitalWrite(ledPin, LOW);
delay(3000);
Serial.print(x);
} else {
// turn LED off:
digitalWrite(ledPin, LOW);
x = x+1;
}
if (buttonState == HIGH && x==3) {
// turn LED off:
digitalWrite(ledPin, LOW);
x = 0;
}
}
When I use this code it works for first case that is LED blinks at 1000 ms delay, but if I toggle switch it again works for first condition. How can I make it to execute second condition i.e. to blink at delay of 2000 ms?
Firstly this is your circuit. I tried this circuit and code and worked for me. I used interrupt for checking button state. And millis calculation is simple.
Frequency = 1 / Period
Period = Ton + Toff
6Hz = 1000 millis / T => T = 166 millis
166 = Ton + Toff (for %50 duty cycle Ton=Toff) => Ton = Toff = 83 millis
enter image description here
const int ledPin = 13;
const int buttonPin = 2;
int state = -1;
bool willLightOn = false;
unsigned long currentDelay = 0;
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(buttonPin), changeState, FALLING);
}
void loop() {
if(state % 3 == 0) { //6Hz
currentDelay = 83;
willLightOn = true;
} else if (state % 3 == 1) { //5Hz
currentDelay = 100;
willLightOn = true;
} else if (state % 3 == 2) { //LED off
currentDelay = 0;
willLightOn = false;
digitalWrite(ledPin, LOW);
}
currentMillis = millis();
if (currentMillis - previousMillis >= currentDelay && willLightOn) {
previousMillis = currentMillis;
digitalWrite(ledPin, !digitalRead(ledPin));
}
}
void changeState() {
state++;
}
Right now your logic checks 3 times for the value of x in a single loop.
Below code toggles light whenever x is greater than zero. x's value is changed when button is pressed.
But there is a big problem here: If button is pressed when there's something else going on in the processor or it is sleeping (like the long delays you want to use), it may be ignored. So you better study interrupts and implement this behavior using them.
if (x > 0)
{
digitalWrite(ledPin, HIGH);
delay(1000 * x);
digitalWrite(ledPin, LOW);
}
if (buttonState == HIGH)
{
x++;
if (x > 3)
x = 0;
}
You should create a global state of the application. This state is where you remember if you are blinking at 50hz/60hz/off. Then you can use a switch to do the right thing.
Then you check if the button is pressed and change the application state.
See my example below:
// constants won't change. They're used here to set pin numbers:
const int buttonPin = 7; // the number of the pushbutton pin
const int ledPin = 6; // the number of the LED pin
// variables will change:
int applicationState = 0;
bool lightOn = true;
int currentDelay = 1000;
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
// variable for reading the pushbutton status
void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}
void loop() {
if (digitalRead(buttonPin) == HIGH) {
applicationState++;
if(applicationState >= 3) {
applicationState = 0;
}
delay(100);
}
switch(applicationState){
case 0:
currentDelay = 1000;
lightOn = true;
break;
case 1:
currentDelay = 2000;
lightOn = true;
break;
case 2:
digitalWrite(ledPin, LOW);
lightOn = false;
break;
}
currentMillis = millis();
if (currentMillis - previousMillis >= currentDelay && lightOn) {
previousMillis = currentMillis;
digitalWrite(ledPin, !digitalRead(ledPin));
}
}
I hope you understand what I try to say and demo with the example code.
Your code can not work:
You do need to check if the button state changes, detect when there is a edge. And make sure you detect a single edge only once.
You must repeat the blinking it in a loop till the button is pressed, then you can change the frequency.
You must check the button while you sleep, otherwise your program do not recognize when you press the button.
To make it work, you must change the complete program.
#define BLINK_SLEEP_TIME <some value> // insert value for 16.6666ms
//return 1 after a positive edge
bool button_read(void)
{
static bool lastState=1; //set this to 1, so that a pressed button at startup does not trigger a instant reaction
bool state = digitalRead(buttonPin);
if(state != lastState)
{
state=lastState;
return state;
}
return 0;
}
//Blink the LED with a given period, till button is pressed
//Times are in x*16.666ms or x/60Hz
//At least one time should be more than 0
void blink(uint8_t ontime, uint8_t offtime)
{
while(1)
{
for(uint8_t i=0;i<ontime;i++)
{
led_setOn();
delay(BLINK_SLEEP_TIME);
if(button_read())
{
return;
}
}
for(uint8_t i=0;i<offtime;i++)
{
led_setOff();
delay(BLINK_SLEEP_TIME);
if(button_read())
{
return;
}
}
}
}
const uint8_t time_table[][]=
{
{0,50},//LED is off
{6,6}, //LED blinks with 5Hz, 60Hz/2/6=5Hz
{5,5}, //LED blinks with 6Hz, 60Hz/2/5=6Hz
}
void endless(void)
{
uint8_t i=0;
for(;;)
{
i++;
if(i>2)
{
i=0;
}
blink(time_table[i][0],time_table[i][1]);
}
}
A better approach would be to use a hardware PWM-Module and change the values after a edge on the button.

How to pause a void in C++ Arduino Uno

My question is very simple but I'm stuck on it for a while now.
I need to make a script that when pushed on a button loop a() is put on pause. And when you press it again it should go from where it ended. But I can't figure out a way to do it.
I hope someone can help me.
This is my code:
int Aan = 1;
int Uit = 0;
int analogPin = A3;
int LED1 = 13;
int LED2 = 12;
int LED3 = 11;
int LED4 = 10;
int val;
bool r = false;
void setup() {
pinMode(analogPin, INPUT_PULLUP);
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
pinMode(LED4, OUTPUT);
digitalWrite(LED1, Aan);
digitalWrite(LED2, Aan);
digitalWrite(LED3, Aan);
digitalWrite(LED4, Aan);
}
void loop() {
val = digitalRead(analogPin);
if (val == LOW)
{
if (r == true)
{
r = false;
}
if (r == false)
{
r = true;
}
}
if (r == true)
{
a();
}
}
void a() {
for (int i = 10; i <= 13; i++)
{
pinMode(i, OUTPUT);
digitalWrite(i, Uit);
delay(100);
digitalWrite(i, Aan);
}
for (int i = 13; i >= 10; i--)
{
pinMode(i, OUTPUT);
digitalWrite(i, Uit);
delay(100);
digitalWrite(i, Aan);
}
}
Just to explain whats happening.. Void a() makes 4 different leds light up and go out. The pattern thats used is Knight Rider (If you don't know the tv show just google the car of him)
I will assume you want the "Knight Rider" pattern to constantly run.
I've made a couple of changes. First, I added a function to run the led sequence one way. Second, I added a while loop that will always run once, and will continue to run while the button is pushed.
bool paused = false;
int buttonState = HIGH;
void loop() {
a();
}
// This only works if leds ports are consecutive
void runSequence(int ledStart, int ledEnd)
{
int direction = ledStart < ledEnd ? 1 : -1;
for (int i = ledStart; i != ledEnd + direction; i += direction) {
digitalWrite(i, Uit);
do {
delay(100);
} while (LOW == digitalRead(analogPin)); // Check button state
digitalWrite(i, Aan);
}
}
void a() {
runSequence(LED4, LED1);
runSequence(LED1, LED4);
}
EDIT Changes based on comment
bool paused = false;
int buttonState = HIGH;
int currentLED = LED1;
int currentDirection = -1;
void loop() {
checkButton();
if (!paused) {
// Flash the led
digitalWrite(currentLED, Uit);
delay(100);
digitalWrite(currentLED, Aan);
// Change direction?
if (LED1 == currentLED || LED4 == currentLED) {
currentDirection *= -1;
}
// Setup for next iteration
currentLED += currentDirection;
}
}
void checkButton() {
int state = digitalRead(analogPin);
// Check if button state has changed
if (state != buttonState) {
buttonState = state;
// Change paused state when button is released
if (state == HIGH) {
paused = !paused;
}
}
}
Inside your a() function put another while loop which becomes false when the button is Up.
Like:
while(digitalRead(analogPin) == LOW)
{
}
As long as the button is pressed down the loop will continue. When you release the button the program will exit the loop and continue execution of your code.