It would help if you post the code you are struggling with.
The way I would do it is to read and save the state of all the buttons and then depending on the saved values call the appropriate function. The demo Several Things at a Time might give you some ideas.
Yeah, sorry. Below is the code. I've added where I want the buttons to react (in the void loop). I looked at your guide for how to run several tasks at once and I am using it in the code. Can't really see how it solves my problem though. Worth mentioning again is that I am using momentary switches.
#define DRUM1 0 //Define port A0
#define DRUM2 1 //Define port A1
#define THRESHOLD 200 //Threshold for trigger to react
#include <DmxMaster.h> //Go get DMX lib
byte val1 = 0;
byte val2 = 0;
int brightness=255;
int time=100;
void setup() {
DmxMaster.usePin(3);
DmxMaster.maxChannel(6);
}
void loop() {
//If button 1 is pressed, run this:
Blink1(time); //virvel
Blink2(time); //kagge
//If button 2 is pressed run this:
Blink3();
//etc.
}
void Blink1 (int interval){
static long prevMill = 0;
val1 = analogRead(DRUM1);
if ( (((long)millis() - prevMill) >= interval) && (val1 > THRESHOLD)){
prevMill = millis();
for (brightness = 255; brightness >= 0; brightness--) {
/* Update DMX channel 1 to new brightness */
DmxMaster.write(1, brightness);
/* Small delay to slow down the ramping */
delay(1);
}//digitalWrite(blueLed, !digitalRead(blueLed));
}
if ( (((long)millis() - prevMill) >= interval) && (val1 < THRESHOLD)){
DmxMaster.write(1, 0);
}
}
void Blink2 (int interval){
static long prevMill = 0;
val2 = analogRead(DRUM2);
if (((millis() - prevMill) >= interval) && (val2 > THRESHOLD+20)){
prevMill = millis();
for (brightness = 255; brightness >= 0; brightness--) {
/* Update DMX channel 1 to new brightness */
DmxMaster.write(17, brightness);
/* Small delay to slow down the ramping */
delay(1);
}
}
if (((millis() - prevMill) >= interval) && (val2 < THRESHOLD)){
DmxMaster.write(17, 0);
}
}
void Blink3(){
for (brightness = 0; brightness >= 255; brightness++) {
/* Update DMX channel 1 to new brightness */
DmxMaster.write(17, brightness);
/* Small delay to slow down the ramping */
delay(1);
}
}
The following code got me somewhere but it seems overly complicated. I also only got it to react to one of the buttons (4) and not the other.
#define DRUM1 0 //Definierar port A0
#define DRUM2 1 //Definierar port A1
#define THRESHOLD 200 //Gränsvärde för när tiggern skall reagera
#include <DmxMaster.h> //Hämtar in DMX-bibliotek
// One side of the button is attached to pin 2, the other to ground.
#define PIN_BUTTON 2
#include "MomentaryButton.h"
MomentaryButton button(PIN_BUTTON);
//0-ar värdet på analogport
byte val1 = 0;
byte val2 = 0;
int ljusstyrka=255;
int tid=100;
int inPin1 = 4; // the pin number for input (for me a push button)
int inPin2 = 5;
int current1; // Current state of the button
int current2;
// (LOW is pressed b/c i'm using the pullup resistors)
long millis_held; // How long the button was held (milliseconds)
long secs_held; // How long the button was held (seconds)
long prev_secs_held; // How long the button was held in the previous check
byte previous1 = HIGH;
byte previous2 = HIGH;
unsigned long firstTime; // how long since the button was first pressed
void setup() {
DmxMaster.usePin(3);
DmxMaster.maxChannel(6);
Serial.begin(9600); // Use serial for debugging
digitalWrite(inPin1, HIGH); // Turn on 20k pullup resistors to simplify switch input
digitalWrite(inPin2, HIGH); // Turn on 20k pullup resistors to simplify switch input
}
void loop() {
current1 = digitalRead(inPin1);
current2 = digitalRead(inPin2);
//Serial.println(current2);
// if the button state changes to pressed, remember the start time
if ( (current1 == LOW && previous1 == HIGH) && (millis() - firstTime) > 200) {
firstTime = millis();
}
if ( (current2 == LOW && previous2 == HIGH) && (millis() - firstTime) > 200) {
firstTime = millis();
}
millis_held = (millis() - firstTime);
secs_held = millis_held / 1000;
// This if statement is a basic debouncing tool, the button must be pushed for at least
// 100 milliseconds in a row for it to be considered as a push.
if (millis_held > 50) {
// check if the butt{on was released since we last checked
if ( current1 == HIGH && previous1 == LOW ) {
// HERE YOU WOULD ADD VARIOUS ACTIONS AND TIMES FOR YOUR OWN CODE
// ===============================================================================
while(previous1==LOW && digitalRead(inPin1)==HIGH && millis_held >100){
Serial.println("In the loop");
Blink1(tid); //virvel
Blink2(tid); //kagge
if(previous1==LOW && digitalRead(inPin1)==LOW && millis_held >200){
break;
} }
}
}
if(digitalRead(inPin1)==LOW){
delay(200);
}
previous1 = current1;
previous2 = current2;
prev_secs_held = secs_held;
Serial.println("Out of the loop");
}
/*=======================================================================
* Trigger 1 activates this
*/
void Blink1 (int interval){
static long prevMill = 0;
val1 = analogRead(DRUM1) ;
if ( (((long)millis() - prevMill) >= interval) && (val1 > THRESHOLD+20)){
prevMill = millis();
for (ljusstyrka = 255; ljusstyrka >= 0; ljusstyrka--) {
/* Update DMX channel 1 to new brightness */
DmxMaster.write(1, ljusstyrka);
/* Small delay to slow down the ramping */
delay(1);
}
}
if ( (((long)millis() - prevMill) >= interval) && (val1 < THRESHOLD)){
DmxMaster.write(1, 0);
}
}
/*=====================================================================
* Trigger 2 activates this
*/
void Blink2 (int interval){
static long prevMill = 0;
val2 = analogRead(DRUM2);
if (((millis() - prevMill) >= interval) && (val2 > THRESHOLD)){
prevMill = millis();
for (ljusstyrka = 255; ljusstyrka >= 0; ljusstyrka--) {
/* Update DMX channel 1 to new brightness */
DmxMaster.write(17, ljusstyrka);
/* Small delay to slow down the ramping */
delay(1);
}
}
if (((millis() - prevMill) >= interval) && (val2 < THRESHOLD)){
DmxMaster.write(17, 0);
}
}
void Blink3(){
for (ljusstyrka = 0; ljusstyrka >= 255; ljusstyrka++) {
/* Update DMX channel 1 to new brightness */
DmxMaster.write(17, ljusstyrka);
/* Small delay to slow down the ramping */
delay(1);
}
}
I'm sorry, I think I explained that wrong. I used your code for the purpose of running loop simultaneously, which worked and is great, BUT now the question lies in turning these loops on and off using momentary buttons, which I can't figure out.
If you should look at one code the first one is probably the best. It only contains the program to run the loops which turn on the lights. No code for buttons added.
The second one is the same code but I added some lines of code for controlling using switches. I just got it working for one switch though, and not two (or more) for some reason. It just wont react. I posted it in hope that it would maybe make things clearer of what I'm trying to accomplish.
Well, thing is is that I would like to be able to exit the loop once the a button is pressed once more. In your code above, entering the loop works, but there is now way to get out of it.
This is what i want from the code:
Imagine that you have 5 lamp buttons on the wall. If i press #1, the lights in the sealing will turn on with a steady light. If i press button #1 again they will turn off.
If i press #2, the lights in the sealing will start blinking. If i press button #2 again they will turn off.
If i press #3, the lights in the sealing will start fading, up and down. If i press button #3 again they will turn off.
And so on...
Btw, thank you for all you help so far @Robin2. Means a lot.
jacobthebluesman:
This is what i want from the code:
Imagine that you have 5 lamp buttons on the wall. If i press #1, the lights in the sealing will turn on with a steady light. If i press button #1 again they will turn off.
Then you need a variable for each button that keeps track of the state of the lights. Let's call the variable lightsON and initialize it to false. With the first press the variable changes to true. On the next press it changes to false etc.
To do that you also need to check that the button changed from HIGH to LOW (assuming LOW means pressed) so that it does not cycle through the sequence at 1000 times a second.
Then you could have a function called lightsFullOn() which checks the variable lightsON to know what to do. You can just call that function every time loop() repeats. The code in loop() could be as simple as
My more experienced friend gave me some support and now I have a working code. This code will turn on LED1 if button 1 is pressed, and turn it off if button one us pressed again. The same goes for LED2 and button 2. Here it is:
//Defining variables
boolean buttonIsPressed = false;
int pressedButton = 0;
int LED1=5;
int LED2=6;
int brightness = 0;
int pin1=2;
int pin2=4;
//======================================================
void setup(){
//Define LED-ports as outputs
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
//Initiate serialprint
Serial.begin(9600);
}
//===================================================
void loop() {
while(!buttonIsPressed) { // Idle mode: no lights are on
if( readButtons() > 0 ) //Reads if any of the buttons where pressed
buttonIsPressed = true; // turns 'buttonIsPressed' to TRUE so that we can leave the idle-loop
Serial.println("Nothing going on"); //Prints that we are not in a case
digitalWrite(LED1,LOW);//Turns of LED1
digitalWrite(LED2,LOW); //Turns of LED2
}
buttonIsPressed = false; // Resets the variable so that we return to the while-loop above after we passed through the 'loop'.
pressedButton = readButtons(); //Stores value for button
delay(50); // Waits for the button to debounc
while( readButtons() != 0); // Waits for the pressed button to be released
delay(50); // Waits for the button to debounce
//======================================================
switch (pressedButton) { // Switches between cases depending on which value 'pressedButton' has. If pressedButton == 1, switches to 'case 1:' and the to 'SWITCHEND'
//====================================================
case 1: // When the first button is pressed
while(readButtons() != 1) { //As long as readButton() returns 1 (button 1 not pressed), this while-loop will run
digitalWrite(LED1,HIGH); //Turns on LED1
Serial.println("case1"); //Prints that we are in case 1
/*To use later for DMX-control
* DmxMaster.write(1, brightness); // Dimming lights, vet inte vad för mönster du vill göra
brightness = brightness + 1; //T
if( brightness > 255)
brightness = 0; // Återställ brightness
delay(1); // Godtycklig delay
*/
}
break;
//======================================================
case 2: // When the second button is pressed
while(readButtons() != 2) { //As long as readButton() returns 2 (button 2 not pressed), this while-loop will run
digitalWrite(LED2, HIGH); //Turns on LED1
Serial.println("case2"); //Prints that we are in case 2
/* To use later for DMX-control
brightness = brightness + 1;
if( brightness > 255)
brightness = 0; // Återställ brightness
delay(1); // Slows down
*/
}
break;
//=====================================================
default:
// If non of the cases are TRUE, that is 'pressedButton' does not equal 1 or 2 (which is unlikley) the process ends up here.
break;
} // SWITCHNEND
//brightness = 0; //Resets brightness
while( readButtons() != 0); //One more debounce saftey
delay(50);
}
//=======================================================
int readButtons(void) {
if(digitalRead(pin1)){
return 1; // 1 means that button one has been pressed
delay(50); } //Debounce
else if(digitalRead(pin2)){
return 2; // 2 means that button 2 has been pressed
delay(50); //Debounce
}
else
return 0; // No button has been pressed, sends value 0
}