i am trying to make an alarm clock with esp8266 and ws2812b leds. On alarm time it must call the sunrise() function. The sunrise() function works fine when i put it directly in the loop function. But it doesn't work in alarm trigger.
if (AlarmData.AlarmOn[Current.Day])
{
if (!AlarmActive)//do not enter this routine if alarm already active
{
if (Current.Hour == AlarmData.Hour[Current.Day])
{
if (Current.Minute == AlarmData.Minute[Current.Day])
{
if (Current.Second > 0 && Current.Second < 3)
{
AlarmActive = true;
sunrise();
alarmTriggerTime = micros();
Serial.println("Its time for your alarm!");
}
}
}
}
}
My code is below. thanks in advance for your help
#include <ESP8266WiFi.h>
#include <ArduinoOTA.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
#include "EEPROMAnything.h"
#include "get_time.h"
#include "OTA.h"
#include <stdio.h>
#include <stdint.h>
#include "web_portal.h"
#include "ESP8266TimerInterrupt.h"
#include "restore_factory_settings.h"
#include "FastLED.h"
#define NUM_LEDS 60
#define DATA_PIN 5
// Define the array of leds
CRGB leds[NUM_LEDS];
#define timeZone 3
#define TenSecs 10000000
#define OneMin 60000000
#define TenMins 600000000
#define TIMER_INTERVAL_MS 1000
ESP8266Timer ITimer;
int timer;
int alarmTriggerTime;
struct CurrentTime Current;
bool AlarmActive;
struct AlarmDataStruct AlarmData;
int WiFiTimer;
char factory_settings_stored [3];
bool OneSecoundPassed;
void ICACHE_RAM_ATTR TimerHandler(void)
{
OneSecoundPassed = true;
}
void setup() {
Serial.begin(115200);
Serial.println("Booting");
EEPROM.begin(512);
EEPROM_readAnything(150, factory_settings_stored);
if (memcmp(&factory_settings_stored, "YES", 3) != 0)
{
restore_factory_settings();
}
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(0);
WiFi.mode(WIFI_STA);
WiFiManager wm;
bool response;
response = wm.autoConnect("AutoConnectAP"); // anonymous ap
if (!response) {
Serial.println("Failed to connect");
// ESP.restart();
}
else {
//if you get here you have connected to the WiFi
Serial.println("Lets Go");
}
start_server();
SetupOTA();
setup_time(timeZone);
Current = Current_Time();
EEPROM_readAnything(100, AlarmData);
Serial.print("Alarm set for ");
Serial.print(AlarmData.Hour[Current.Day]);
Serial.print(":");
Serial.println(AlarmData.Minute[Current.Day]);
timer = micros();
WiFiTimer = timer;
// Interval in microsecs
if (ITimer.attachInterruptInterval(TIMER_INTERVAL_MS * 1000, TimerHandler))
{
Serial.println("Starting ITimer OK, millis() = " + String(millis()));
}
else
{
Serial.println("Can't set ITimer correctly. Select another freq. or interval");
}
}
void loop() {
if (!AlarmActive)
{
ArduinoOTA.handle();
handle_client();
if ((micros() - WiFiTimer) > TenMins) // check if wifi connection lost and if so try to reconnect
{
if (WiFi.status() != WL_CONNECTED)
{
ESP.restart(); //try to reconnect rather than resetting
}
WiFiTimer = micros();
}
if (OneSecoundPassed)
{
updateLocalTime();
OneSecoundPassed = false;
}
//update current hour from NTP server
if ((micros() - timer) > TenMins)
{
Current = Current_Time();
timer = micros();
}
}
if (AlarmActive)
{
if ((micros() - alarmTriggerTime) > TenMins)
{
AlarmActive = false; //if alarm active for 10mins and no one switches it off then do it auto
}
}
if (AlarmData.AlarmOn[Current.Day])
{
if (!AlarmActive)//do not enter this routine if alarm already active
{
if (Current.Hour == AlarmData.Hour[Current.Day])
{
if (Current.Minute == AlarmData.Minute[Current.Day])
{
if (Current.Second > 0 && Current.Second < 3)
{
AlarmActive = true;
sunrise();
alarmTriggerTime = micros();
Serial.println("Its time for your alarm!");
}
}
}
}
}
else
{
if (!AlarmActive)
{
}
}
}
void updateLocalTime () {
Current.Second++;
if (Current.Second >= 60)
{
Current.Second = 0;
Current.Minute++;
if (Current.Minute >= 60)
{
Current.Minute = 0;
Current.Hour++;
if (Current.Hour >= 24)
{
Current.Hour = 0;
Current.Day++;
if (Current.Day >= 7)
{
Current.Day = 0;
}
}
}
}
char tempTime[6];
if (Current.Minute < 10 && Current.Second < 10)
{
sprintf(tempTime, "0%d:0%d", Current.Minute, Current.Second);
}
else if (Current.Minute < 10)
{
sprintf(tempTime, "0%d:%d", Current.Minute, Current.Second);
}
else if (Current.Second < 10)
{
sprintf(tempTime, "%d:0%d", Current.Minute, Current.Second);
}
else
{
sprintf(tempTime, "%d:%d", Current.Minute, Current.Second);
}
}
void sunrise() {
static const uint8_t sunriseLength = 30; //(min)
static const uint8_t interval = (sunriseLength * 60) / 256;
static const uint8_t binterval = (sunriseLength * 60) / 256;
// current gradient palette color index
static uint8_t heatIndex = 0; // start out at 0
static uint8_t brIndex = 0;
// HeatColors_p is a gradient palette built in to FastLED
// that fades from black to red, orange, yellow, white
// feel free to use another palette or define your own custom one
CRGB color = ColorFromPalette(HeatColors_p, heatIndex);
fill_solid(leds, NUM_LEDS, color); // fill the entire strip with the current color
EVERY_N_SECONDS(binterval) {
if (brIndex < 255) {
FastLED.setBrightness(brIndex);
brIndex++;
}
}
EVERY_N_SECONDS(interval) {
if (heatIndex < 255) {
heatIndex++;
}
}
FastLED.show();
}
Your sunrise function should be called over and over, every call changes the LED color a slight bit. This is why it works then you put it into the loop function.
However, you have guarded it so that it is specifically only called once - so now it is called, sets the LEDs to the dimmest setting possible, and is not called again.
What you need to do is separate this out into two parts: One that detects when to activate sunrise, and one that is continuously called when it is time. F.ex:
void loop()
{
/* stuff */
if (AlarmData.AlarmOn[Current.Day])
{
if (!AlarmActive) // do not enter this routine if alarm already active
{
if (Current.Hour == AlarmData.Hour[Current.Day])
{
if (Current.Minute == AlarmData.Minute[Current.Day])
{
if (Current.Second > 0 && Current.Second < 3)
{
AlarmActive = true;
alarmTriggerTime = micros();
Serial.println("Its time for your alarm!");
}
}
}
}
}
if (AlarmActive)
sunrise();
}
Related
#define CLK 2
#define DT 3
#define SW 4
#include <EEPROM.h>
#include <Wire.h>
#include <LiquidCrystal_PCF8574.h>
LiquidCrystal_PCF8574 lcd(0x27);
int counter = 0;
int currentStateCLK;
int lastStateCLK;
int lastCLK,cnt=0,btnState,lastPress=0;
String currentDir ="";
unsigned long lastButtonPress = 0;
char *mainmenu[] ={"SET MODE","SET TEMP","SET HUMD","SERVO","RESET"};
char *setmode[] ={"INCUBATOR","HATCHER","BACK"};
void setup() {
// Set encoder pins as inputs
Wire.begin();
Wire.beginTransmission(0x27);
pinMode(CLK,INPUT);
pinMode(DT,INPUT);
pinMode(SW, INPUT_PULLUP);
lcd.begin(16, 2);
lcd.setBacklight(255);
lcd.home(); lcd.clear();
Serial.begin(9600);
lastStateCLK = digitalRead(CLK);
delay(100);
if(EEPROM_READ(0)==NULL){
SET_MODE();
}
Serial.print(EEPROM_READ(0));
}
void loop(){
disp();
rot();
}
void disp(){
lcd.setCursor(0,0);
lcd.print(" KGF");
}
void rot() {
int lim=sizeof(mainmenu)/2;
Serial.print(lim);
currentStateCLK = digitalRead(CLK);
if (currentStateCLK != lastStateCLK && currentStateCLK == 1){
lcd.clear();
lcd.setCursor(0, 1);
if (digitalRead(DT) != currentStateCLK) {
counter --;
if(counter<0){
counter=lim-1;
}
}
else {
// Encoder is rotating CW so increment
counter ++;
if(counter>lim-1){
counter=0;
}
lcd.print(mainmenu[counter]);
}
lastStateCLK = currentStateCLK;
int btnState = digitalRead(SW);
if (btnState == LOW) {
//if 50ms have passed since last LOW pulse, it means that the
//button has been pressed, released and pressed again
if (millis() - lastButtonPress > 50) {
if(counter==0){
SET_MODE();
}
}
}
lastButtonPress = millis();
}
delay(1);
}
void SET_MODE(){
int lim=sizeof(setmode)/2;
int currentCLK = digitalRead(CLK);
if (currentCLK != lastCLK && currentCLK == 1){
lcd.clear();
lcd.setCursor(0, 1);
if (digitalRead(DT) != currentCLK) {
cnt --;
if(cnt<0){
cnt=lim-1;
}
}
else {
// Encoder is rotating CW so increment
cnt ++;
if(cnt>lim-1){
cnt=0;
}
}
lcd.print(setmode[cnt]);
}
lastCLK = currentCLK;
btnState = digitalRead(SW);
if (btnState == LOW) {
//if 50ms have passed since last LOW pulse, it means that the
//button has been pressed, released and pressed again
if (millis() - lastButtonPress > 50) {
if(setmode[cnt]=="BACK"){
exit(0);
}
lcd.clear();
lcd.setCursor(0, 1);
EEPROM_WRITE(0,setmode[cnt]);
lcd.print("DONE");
}
lastPress = millis();
}
delay(1);
}
void EEPROM_WRITE(int addrOffset, const String &strToWrite)
{
byte len = strToWrite.length();
EEPROM.write(addrOffset, len);
for (int i = 0; i < len; i++)
{
EEPROM.write(addrOffset + 1 + i, strToWrite[i]);
}
}
String EEPROM_READ(int addrOffset)
{
int newStrLen = EEPROM.read(addrOffset);
char data[newStrLen + 1];
for (int i = 0; i < newStrLen; i++)
{
data[i] = EEPROM.read(addrOffset + 1 + i);
}
data[newStrLen] = '\0';
return String(data);
}
I want to call the SET_MODE() function in the loop from rot() function, I am building a menu based program so the SET MODE menu should redirect to the SET_MODE() function, and as I will be adding more menu and sub-menus how can I perform this task.
The SET_MODE() function doesn't work in loop I do not know why, it only works when I all it under void loop() directly.
I have this IOT project which controls my chameleon's terrarium. It has a relay connected to D5 and D6 pins to control lights. My Nodemcu 0.9 stops working after ~ 20 hours (lights are off at this time and won't turn back on, I always have to reset my nodemcu).
I've been reading stack and found that strings use a lot of heap memory, so I removed all of them but the problem still persists.
main.cpp
#include <FirebaseArduino.h>
#include <NTPClient.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiUdp.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include "credentials.h"
#define DHTPIN D7
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
double previousTemperature = 0.0;
double previousHumidity = 0.0;
boolean overRide = false;
boolean uvStatus;
boolean irStatus;
int baskingTime;
int startHour;
int startMinute;
int endTime;
int startTimeMinutes;
int endTimeMinutes;
const int uvPin = D5;
const int irPin = D6;
const char *ssid = "Waifas 2.4";
const char *password = "lsmustud";
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 7200, 60000);
void setup()
{
pinMode(uvPin, OUTPUT);
pinMode(irPin, OUTPUT);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
}
timeClient.begin();
//initialize firebase
Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
Firebase.setBool(OVERRIDE, false);
baskingTime = Firebase.getInt(BASKING_TIME);
startHour = Firebase.getInt(START_HOUR);
startMinute = Firebase.getInt(START_MINUTE);
uvStatus = Firebase.getBool(UV_STATUS);
irStatus = Firebase.getBool(IR_STATUS);
startTimeMinutes = startHour * 60 + startMinute;
endTimeMinutes = startHour * 60 + startMinute + baskingTime * 60;
Firebase.stream(DB_PATH);
dht.begin();
}
void loop()
{
timeClient.update();
int clientHour = timeClient.getHours();
int clientMinute = timeClient.getMinutes();
int currentTimeMinutes = clientHour * 60 + clientMinute;
if (Firebase.failed())
{
delay(1000);
Firebase.stream(DB_PATH);
return;
}
if (Firebase.available())
{
FirebaseObject event = Firebase.readEvent();
String eventPath = event.getString("path");
eventPath.toLowerCase();
if (eventPath == "/override")
{
overRide = Firebase.getBool(OVERRIDE);
}
if (eventPath == "/uvstatus")
{
uvStatus = Firebase.getBool(UV_STATUS);
}
if (eventPath == "/irstatus")
{
irStatus = Firebase.getBool(IR_STATUS);
}
if (eventPath == "/baskingtime" || eventPath == "/starthour" || eventPath == "/startminute")
{
baskingTime = Firebase.getInt(BASKING_TIME);
startHour = Firebase.getInt(START_HOUR);
startMinute = Firebase.getInt(START_MINUTE);
endTime = startHour + baskingTime;
if (endTime >= 24)
{
endTime = endTime - 24;
}
startTimeMinutes = startHour * 60 + startMinute;
endTimeMinutes = endTime * 60 + startMinute;
}
}
if (!overRide)
{
if (startTimeMinutes <= currentTimeMinutes && currentTimeMinutes <= endTimeMinutes)
{
if (!uvStatus)
{
Firebase.setBool(UV_STATUS, true);
uvStatus = true;
}
if (!irStatus)
{
Firebase.setBool(IR_STATUS, true);
irStatus = true;
}
}
else
{
if (uvStatus)
{
Firebase.setBool(UV_STATUS, false);
uvStatus = false;
}
if (irStatus)
{
Firebase.setBool(IR_STATUS, false);
irStatus = false;
}
}
}
if (uvStatus)
{
digitalWrite(uvPin, LOW);
}
else
{
digitalWrite(uvPin, HIGH);
}
if (irStatus)
{
digitalWrite(irPin, LOW);
}
else
{
digitalWrite(irPin, HIGH);
}
double t = dht.readTemperature();
double h = dht.readHumidity();
if (isnan(h) || isnan(t))
{
}
else
{
if (h != previousHumidity)
{
previousTemperature = h;
Firebase.setFloat(HUMIDITY, h);
}
if (t != previousTemperature)
{
previousTemperature = t;
Firebase.setFloat(TEMPERATURE, t);
}
}
delay(1000);
}
Credentials.h
//define firebase login
#define FIREBASE_HOST "someDatabase.someGoogleLink.com"
#define FIREBASE_AUTH "someSecret"
//db path
#define DB_PATH "/control/"
#define BASKING_TIME "/control/baskingTime"
#define IR_STATUS "/control/irStatus"
#define UV_STATUS "/control/uvStatus"
#define START_MINUTE "/control/startMinute"
#define START_HOUR "/control/startHour"
#define OVERRIDE "/control/overRide"
#define TEMPERATURE "/temperature"
#define HUMIDITY "/humidity"
Would you help me to fix this? I'm not a programmer, just a hobbyist, so it is really hard for me to figure this out.
So in my current RTOS code for mbed I have a timer that counts down from 3 minutes displayed in the format of minutes:seconds.I need to implement way so when the time gets to under a minute, the time is displayed in hundredths of a second, such as 59:59. How would I do that?
Here is my current code (the relevant code for displaying time is under void lcd_func (void const *args)):
#include "mbed.h"
#include "cmsis_os.h"
#include "scoreboard.h"
#define deb 180
C12832 lcd(p5, p7, p6, p8, p11);
LM75B sensor(p28,p27);
InterruptIn By1(p15); // Up on the Joystick
InterruptIn By2(p16); // Right on the Joystick
InterruptIn By3(p12); // Down on the Joystick
InterruptIn Team(p14); // Push on the Joystick
InterruptIn Play(p13); // Left to activate clock
// declaration of IDs handle for various threads
osThreadId score_ID, LCD_ID, time_ID, temp_ID;
// definition of the thread
osThreadDef(score_func, osPriorityNormal, DEFAULT_STACK_SIZE);
osThreadDef(lcd_func, osPriorityNormal, DEFAULT_STACK_SIZE);
osThreadDef(time_func, osPriorityNormal, DEFAULT_STACK_SIZE);
osThreadDef(temp_func, osPriorityNormal, DEFAULT_STACK_SIZE);
// message from ISrs
osMessageQDef(queue, 1, uint32_t);
osMessageQId(queue_ID);
// service routines for Joystick Up, Right and Down
void By1_isr() {osMessagePut(queue_ID, 1, 0);}
void By2_isr() {osMessagePut(queue_ID, 2, 0);}
void By3_isr() {osMessagePut(queue_ID, 3, 0);}
void Team_isr();
void Time_isr();
Timer t;
int minutes,seconds,zero,faults;
int main()
{
t.start();//start the timer
By1.rise(&By1_isr);
By2.rise(&By2_isr);
By3.rise(&By3_isr);
Team.rise(&Team_isr);
Play.rise(&Time_isr);
queue_ID = osMessageCreate(osMessageQ(queue), NULL);
score_ID = osThreadCreate(osThread(score_func), NULL);
LCD_ID = osThreadCreate(osThread(lcd_func), NULL);
time_ID = osThreadCreate(osThread(time_func), NULL);
temp_ID = osThreadCreate(osThread(temp_func), NULL);
}
void Team_isr()
{
if(t.read_ms() > deb) {
score.h0v1 = !score.h0v1;
osSignalSet(LCD_ID, 0x2);
t.reset();
}
}
void Time_isr()
{
if (score.running == 0)
{
score.running = 1;
}
else
{
faults++;
score.running = 0;
}
osSignalSet(time_ID, 0x3);
}
void Timer1_Update (void const *args)
{
score.time_count -= 1;
osSignalSet(LCD_ID, 0x2);
}
void Destroy(float val)
{
osThreadTerminate(time_ID);
osThreadTerminate(score_ID);
osThreadTerminate(LCD_ID);
lcd.cls();
lcd.locate(0,3);
lcd.printf("Gamed Terminated!\n");
lcd.printf("(temperature reached %2.1f)\n", val);
osThreadTerminate(temp_ID);
}
void score_func (void const *args)
{
score.h0v1 = 0; // home by default
score.time_count = 180;
score.home_count = 0;
score.visitors_count = 0;
uint32_t val;
while (1) {
osEvent score_sig = osMessageGet(queue_ID, osWaitForever);
if (score_sig.status == osEventMessage)
val = score_sig.value.v;
if (score.h0v1 == 0)
score.home_count += val;
else
score.visitors_count += val;
osSignalSet(LCD_ID, 0x2);
}
}
void lcd_func (void const *args)
{
while(1) {
minutes=score.time_count/60;
seconds=score.time_count%60;
if (seconds<10)
{
lcd.cls();
lcd.locate(0,3);
lcd.printf("Time remaining: %2d:%d%d\n",minutes,zero,seconds);
}
else{
lcd.cls();
lcd.locate(0,3);
lcd.printf("Time remaining: %2d:%2d\n",minutes,seconds);}
if (score.h0v1 == 0)
lcd.printf("*Home: %2d Visitors: %2d\n",
score.home_count, score.visitors_count);
else
lcd.printf(" Home: %2d *Visitors: %2d\n",
score.home_count, score.visitors_count);
osSignalWait(0x2, osWaitForever);
}
}
void time_func (void const *args)
{
osTimerDef (Timer1, Timer1_Update);
osTimerId Timer1_ID;
// Activate time
Timer1_ID = osTimerCreate (osTimer(Timer1), osTimerPeriodic, NULL);
while(1) {
osSignalWait(0x3, osWaitForever);
if (score.running == 0)
osTimerStop (Timer1_ID);
else
osTimerStart (Timer1_ID, 1000UL);
}
}
void temp_func (void const *args)
{
float temp;
if (sensor.open()) {
sensor.alertTemp(40.0);
while (1) {
temp = (float)sensor.temp();
if (temp > 30.0)
Destroy(temp);
osDelay(5000);
}
}
else
osThreadTerminate(temp_ID);
}
Change your timer to decrement every 100th and start at 18000. Then:
minutes = score.time_count / 6000;
seconds = (score.time_count % 6000) / 100 ;
hundredths = score.time_count % 100 ;
...
if( minutes == 0 )
{
lcd.printf( "Time remaining: 00:%2d:%2d\n", seconds, hundredths ) ;
}
else
{
lcd.printf( "Time remaining: %2d:%2d:00\n", minutes, seconds ) ;
}
For school I am making a clapping sensor with my arduino nano. I have found some code to detect if there are 2 claps (link). But now I want to modify the code so it can distinguish if I clapped 1,2 or 3 times. I have now changed the source to detect 1 or 2 claps. But now if I clap twice, always a one clap is detected before it sees the 2 claps. And i have totally no idea how to detect 3 claps. Can someone please help me with this problem?
Code:
#define signalToRelayPin 12
#define sensorPin 7
int lastSoundValue;
int soundValue;
long lastNoiseTime = 0;
long currentNoiseTime = 0;
long lastLightChange = 0;
int relayStatus = HIGH;
void setup() {
pinMode(sensorPin, INPUT);
pinMode(signalToRelayPin, OUTPUT);
Serial.begin(115200);
}
struct DataBlockStruct meting1,meting2;
void loop() {
soundValue = digitalRead(sensorPin);
currentNoiseTime = millis();
if (soundValue == 1) { // if there is currently a noise
if (
(currentNoiseTime > lastNoiseTime + 200) && // to debounce a sound occurring in more than a loop cycle as a single noise
(lastSoundValue == 0) && // if it was silent before
(currentNoiseTime < lastNoiseTime + 800) && // if current clap is less than 0.8 seconds after the first clap
(currentNoiseTime > lastLightChange + 1000) // to avoid taking a third clap as part of a pattern
) {
relayStatus = !relayStatus;
Serial.println("2 X CLAP");
} else {
Serial.println("1 X CLAP");
}
lastNoiseTime = currentNoiseTime;
}
lastSoundValue = soundValue;
}
Try this snippet:
#define signalToRelayPin 12
#define sensorPin 7
int lastSoundValue;
int soundValue;
long lastNoiseTime = 0;
long currentNoiseTime = 0;
long lastLightChange = 0;
int relayStatus = HIGH;
int clap_interval = 500;
int claps = 0;
void setup() {
pinMode(sensorPin, INPUT);
pinMode(signalToRelayPin, OUTPUT);
Serial.begin(115200);
}
struct DataBlockStruct meting1,meting2;
void loop() {
soundValue = digitalRead(sensorPin);
currentNoiseTime = millis();
if (soundValue == 1 && lastSoundValue == 0)
{
if (claps == 0) // allow first to register without much condition
{
claps = 1;
lastNoiseTime = currentNoiseTime;
}
else
{
if (currentNoiseTime > lastNoiseTime + clap_interval)
{
claps++;
lastNoiseTime = currentNoiseTime;
relayStatus = !relayStatus;
}
}
}
else
{
if (currentNoiseTime > lastNoiseTime + 2 * clap_interval) // no claps for a longer duration time to print and/or reset clap
{
if (claps > 0)
{
Serial.print(claps);
Serial.println(" CLAPS");
claps = 0; ///reset
}
}
}
//lastSoundValue = soundValue;
delay(50); // delay polling
}
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.