Thank you so much for being here to help each other grow, it is appreciated.
I have been on the steep end of the learning curve for a few days trying to get a coherent code complied. I can get individual steps to work, but once mashed together the flow seems to fall wayward. The last section i am stuck on is a simple time out for an LED. I can get it to come on with the time interval that it is to turn off. I can get nothing, or just get the lights to stay on, no matter how I have tried the code I cannot grasp the steps involved.
Bottom line..... when button pushed 3 times UVLED's turn on and need to stay on for 15 min, then shut off, or shut off when button push = 5 . I am close but jumbling this last bit of the code.
As it sits when button push = 3 the lights "flash" on/off 4000mills after button press, then repeats the "flash" every 4000mills.
I have put the uvLightsOut function at the bottom,
// pin connections constant won't change:
const int buttonPin = 2; // the pin that the pushbutton is attached to
const int ledPins[] ={8, 9, 10 }; //the pins that the ambient LED's are attached to
const int motorPin = 3; //the pin the motor is attached to
const int uvPin = 4; // the pin that the UV LED's are attached to
//const int speakerPin = 5; //TBA pin the attached connect to
// Button control Variables will change:
int buttonPushCounter = 0; // counter for the number of button presses
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button
// UV timeout settings
int ledState = LOW;
unsigned long uvPreviousMillis = 0;
const long uvTimeOut = 4000; //TBA 900000 (15 min) for final code
//knight rider timing
unsigned long previousMillis = 0;
static long TIMER = 75;
int knightLight = 0;
int knightCounter = 1;
void setup() {
//knight rider setup start
for (int p = 0; p < 3; p++) {
pinMode(ledPins[p], OUTPUT);
} //knight rider setup end
// Initialize button pin
pinMode(buttonPin, INPUT_PULLUP); // initialize the button pin as a input:
// initialize the uvLED's,motor and speaker as an output:
pinMode(motorPin, OUTPUT);
pinMode(uvPin, OUTPUT);
//pinMode(speakerPin, OUTPUT);
Serial.begin(9600); // initialize serial communication:
}
void loop() {
// read the pushbutton input pin:
buttonState = digitalRead(buttonPin);
// compare the buttonState to its previous state
if (buttonState != lastButtonState) {
// if the state has changed, increment the counter
if (buttonState == HIGH) {
// if the current state is HIGH then the button went from off to on:
buttonPushCounter++;
Serial.print("Button Pushes");
Serial.println(buttonPushCounter);
}
}
// save the current state as the last state, for next time through the loop
lastButtonState = buttonState;
// Controlling the Clicks
if (buttonPushCounter ==1<=5) {
knightRider(); //one click turns on the ambient LED with effect
}
if (buttonPushCounter == 2){
digitalWrite(motorPin, HIGH); //two cliks turns on the motor while ambient LED stays on
}
if (buttonPushCounter == 3){
uvLightsOut();
} //three clicks turns on the uvLEDs while motor & ambient LEDs stays on
if (buttonPushCounter == 4){
//digitalWrite(speakerPin, HIGH); //four clicks turns on speaker
}
if (buttonPushCounter == 5){
digitalWrite(motorPin, LOW);
digitalWrite(uvPin, LOW);
// digitalWrite(speakerPin, LOW); //Five clicks turns all LED's, motor and speaker off
}
if(buttonPushCounter == 5)buttonPushCounter = 0; //reset button counter to 0
}
//knightRider function
void knightRider() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > TIMER) {
previousMillis = currentMillis;
// reset last knightlight
digitalWrite(ledPins[knightLight], LOW);
// calc new knight light
knightLight = knightLight + knightCounter;
if (knightLight > 3 ) {
knightLight = 3;
knightCounter = -1;
}
if (knightLight < 0) {
knightLight = 0;
knightCounter = 1;
}
// set new knight light
digitalWrite(ledPins[knightLight], HIGH);
}
}
// Timeout for UV light Function
void uvLightsOut() {
// check to see if it's time to turn off the uvLED; that is, if the difference
// between the current time and last time you turned on the LED is bigger than
// the timeOut at which you want to turn off the uvLED.
unsigned long uvCurrentMillis = millis();
if (uvCurrentMillis - uvPreviousMillis >= uvTimeOut) {
// save the time uvLED turned on
uvPreviousMillis = uvCurrentMillis;
if (buttonPushCounter == 3);{
digitalWrite(uvPin, HIGH);
}
// if the LED is on turn it off
if (ledState == HIGH) {
ledState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(uvPin, ledState);
}
}
I forgot that was there. Early on in my head logic I was having the knight rider effect turn off when pushing button the second time to turn on the motor. So the logic in my head was if the push counter is 1 turn on but keep looping if two three or four is in the button counter, but pay attention to count #5. It seemed to work in the tinkercad simulator. I was pulling at straws, it passed the debugger and for some reason it worked. I thought i cleaned it up but it is still sitting in the sim and the sim works minus the uv led time out
if (buttonPushCounter ==1<=5) {
knightRider(); //one click turns on the ambient LED with effect
}
yes i see that and when that is out in the code the uvled come on and stay on. I am trying to get the uvtimeout to work with that. i call the digitalWrite in the uvTimeOut Loop to at least get the lights to momentarily flash at my set rate.
looking at the last section......being a clone of blink without delay,
void uvLightsOut() {
// check to see if it's time to turn off the uvLED; that is, if the difference
// between the current time and last time you turned on the LED is bigger than
// the timeOut at which you want to turn off the uvLED.
unsigned long uvCurrentMillis = millis();
if (uvCurrentMillis - uvPreviousMillis >= uvTimeOut) {
// save the time uvLED turned on
uvPreviousMillis = uvCurrentMillis;
if (buttonPushCounter == 3);{
digitalWrite(uvPin, HIGH);
}
// if the LED is on turn it off
if (ledState == HIGH) {
ledState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(uvPin, ledState);
}
cannot i not cut it short?, so it reads uvPin HIGH, start clock, turn off after 4000mills, and dont turn on again. As you can see i removed the
// pin connections constant won't change:
const int buttonPin = 2; // the pin that the pushbutton is attached to
const int ledPins[] = {8, 9, 10 }; //the pins that the ambient LED's are attached to
const int motorPin = 3; //the pin the motor is attached to
const int uvPin = 4; // the pin that the UV LED's are attached to
//const int speakerPin = 5; //TBA pin the attached connect to
// Button control Variables will change:
int buttonPushCounter = 0; // counter for the number of button presses
int buttonState = 0; // current state of the button
int lastButtonState = 1; // previous state of the button
unsigned long lastPush = 0;
byte intervalDebounce = 50;
// UV timeout settings
int ledState = LOW;
unsigned long uvPreviousMillis = 0;
const long uvTimeOut = 4000; //TBA 900000 (15 min) for final code
bool timeExpired = false;//have we timed out yet..
//knight rider timing
unsigned long previousMillis = 0;
static long TIMER = 75;
int knightLight = 0;
int knightCounter = 1;
void setup() {
//knight rider setup start
for (int p = 0; p < 3; p++) {
pinMode(ledPins[p], OUTPUT);
} //knight rider setup end
// Initialize button pin
pinMode(buttonPin, INPUT_PULLUP); // initialize the button pin as a input:
// initialize the uvLED's,motor and speaker as an output:
pinMode(motorPin, OUTPUT);
pinMode(uvPin, OUTPUT);
//pinMode(speakerPin, OUTPUT);
Serial.begin(9600); // initialize serial communication:
}
void loop() {
unsigned long now = millis();
if (now - lastPush >= intervalDebounce) {
// read the pushbutton input pin:
buttonState = digitalRead(buttonPin);
// compare the buttonState to its previous state
if (buttonState != lastButtonState) {
lastPush = now;//start debouncing..
lastButtonState = buttonState;
// if the state has changed, increment the counter
if (buttonState == HIGH) {
// if the current state is HIGH then the button went from off to on:
buttonPushCounter++;
Serial.print("Button Pushes");
Serial.println(buttonPushCounter);
if (buttonPushCounter == 3) uvPreviousMillis = now;//set count down timer..
}
}
}
// save the current state as the last state, for next time through the loop
// Controlling the Clicks
if (buttonPushCounter > 0) {
knightRider(); //one click turns on the ambient LED with effect
}
if (buttonPushCounter > 1) {
digitalWrite(motorPin, HIGH); //two cliks turns on the motor while ambient LED stays on
}
if (buttonPushCounter > 2) {
if (!timeExpired) {
//turn uv lights on..
digitalWrite(uvPin, HIGH);
ledState = HIGH;
}
uvLightsOut();
} //three clicks turns on the uvLEDs while motor & ambient LEDs stays on
if (buttonPushCounter > 3) {
//digitalWrite(speakerPin, HIGH); //four clicks turns on speaker
}
if (buttonPushCounter > 4) {
digitalWrite(motorPin, LOW);
digitalWrite(uvPin, LOW);
// digitalWrite(speakerPin, LOW); //Five clicks turns all LED's, motor and speaker off
}
if (buttonPushCounter == 5)buttonPushCounter = 0; //reset button counter to 0
}
//knightRider function
void knightRider() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > TIMER) {
previousMillis = currentMillis;
// reset last knightlight
digitalWrite(ledPins[knightLight], LOW);
// calc new knight light
knightLight = knightLight + knightCounter;
if (knightLight > 3 ) {
knightLight = 3;
knightCounter = -1;
}
if (knightLight < 0) {
knightLight = 0;
knightCounter = 1;
}
// set new knight light
digitalWrite(ledPins[knightLight], HIGH);
}
}
// Timeout for UV light Function
void uvLightsOut() {
// check to see if it's time to turn off the uvLED; that is, if the difference
// between the current time and last time you turned on the LED is bigger than
// the timeOut at which you want to turn off the uvLED.
unsigned long uvCurrentMillis = millis();
if (uvCurrentMillis - uvPreviousMillis >= uvTimeOut) {
//time to turn off..
timeExpired = true;//our time has expired
ledState = LOW;//set led state low
// set the LED with the ledState of the variable:
digitalWrite(uvPin, ledState);
}
}
should clear the code up..
now that breadboard is a bit scary..
the uno is not a power source, it's digital pins are rated to 20ma..
8 uv leds on one pin is too much and the motor too..
Need to use external power supply and transistors for the uv and motor..
The actual parts needed depends on current consumption..
Maybe you are already aware of all of this??
at about midnight i realized a bool would be needed after researching then crashed as i tried putting things together. Much respect for your skills. Any good sources that you can recommend to explain bool better. I understand it is a true false bucket, but c++ documentation I have come across is only as clear as mud.
I see where the triggers are placed for the millis count.
Yah she loaded.... This is why i am using the sim instead of a real board at the moment. The motor is powered and controlled with its own controller, the red LED is on the power switch, and powered separate from the board. Leaves me with the LED's that will need external power source, still. This project is my jump into learning new skills for an old ditch digger.
I have learned so much from the community here that it gives me hope I can see this project through. it's all baby steps.
That being said, this project is for an open source project to revitalize water. improving water quality and structure is a passion, and I figured I would take all my analog methods and try automating the process. The market has such devices for hundreds to thousands of dollars , this project is to get a fully loaded system for under $100. If anyone is interested in knowing more let me know and I can share links to the project as it sits. 3D printer arrives next week to get into testing of some of the build components.
Everyone have a darn great day..
PS. The code works great in the sim. Now to expand to external power source control.
that's the Knightrider, only got one led per pin, best to leave that off the relays, relays are slow switchers, might mess the effect..
besides the digital pin can easily handle one led..
That i understand, for sim purpose it was used to represent a ( DC 5V-35V 5A Mini DC Motor PWM Speed Controller,Speed Adjustable Switch Module,6V 12V 24V Variable Voltage Regulator with LED Indicator) this is what the mock up has been running on for weeks. So that needs to be connected to the relay to get the on/off signal. An arduino 4 rlay shield should do the trick no?
Pic of the mock up to prove concept. In this state alone it works quite well, i am pushing for a little better refinement.
quick look and scan that is placed between the arduino and the the motor controller. any inductance feedback from the motor through the motor controller is snuffed at the transistor.
totally high level recap here
I have build a WOKWI-simulation for your setup
and used user @qubits-us code posted in post # 7 to test it
The first cycle of button pushes 1,2,3,4,5 works.
But on the second, third 4th.... cycle 1,2,3,4,5
The UV-Leds are not switched on.
After 5 button-press the knight-rider leds stay as they are.
I modified this to switch them all off
I took this code as a base and did modificate it with these aims:
put code and variables that belong to each other and that do not interact with other code into their own function. => code is more structured
Using a non-bocking timing function that reduces the number of variables that are nescessary to make the non-blocking timing work.
Again variables that belong to the timing and that must not interact with other code are inside the function => code is more structured and easier to understand.
The code is shorter and / or easier to analyse and understand.