I am trying to toggle LEDs on and off based on two scenarios.
a counter.(input from two buttons - one for counting up and the other for counting down)
a specific time for led to be ON
if counter is equal to 1: turn ON led 1 for x amount of time (specify at index 0 of the Time array) - all other leds are off;
if counter is equal to 2: turn off the previous led that was ON (even if the specify time of ON for that led was not elapsed) then turn ON led 2 for x amount of time.
the above should be same for all 5 indexes.
here is the code I have got so far for counting the button presses:
//Buttons//
const uint8_t MINBTNCOUNT = 0;
const uint8_t MAXBTNCOUNT = 4;
//Button1// count up
uint8_t buttonPin = 2;
uint8_t buttonPressCount = 0;
uint8_t lstbuttonPressCount = 0;
uint8_t PUSHED = 0;
unsigned long timePushed = 0;
uint8_t currentButtonState = HIGH;
uint8_t lastButtonState = HIGH;
uint32_t millisTimePress = 0;
//Button2// count down///
uint8_t buttonPin2 = 3;
uint8_t buttonPressCount2 = 0;
uint8_t lstbuttonPressCount2 = 0;
uint8_t PUSHED2 = 0;
unsigned long timePushed2 = 0;
uint8_t currentButtonState2 = HIGH;
uint8_t lastButtonState2 = HIGH;
uint32_t millisTimePress2 = 0;
////Leds/////
const int ledPins[] = {4, 5, 6, 7, 8}; // array of leds pins
const int numOfLeds = (sizeof(ledPins) / sizeof(ledPins[0])); // size of Leds
//time translating//
#define sec * 1000
#define min * 60000
#define ms * 1
// LEDS ON Time Lengths //
const unsigned long ledOnTime[] = {19 sec, 44 sec, 9 sec, 7 sec, 33 sec};
void setup() {
Serial.begin(115200);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(buttonPin2, INPUT_PULLUP);
// setting up the digital pins for the leds to be an output //
for (int j = 0; j < numOfLeds; j++)
{
pinMode(ledPins[j], OUTPUT);
}
}
void loop() {
buttonPress1 ();
buttonPress2 ();
}
void buttonPress1 ()
{
byte currentButtonState = digitalRead (buttonPin);
if (lastButtonState != currentButtonState) {
lastButtonState = currentButtonState;
delay (35); // debounce
//******************
//has the switch been pushed ?
if (currentButtonState == PUSHED)
{
//record the time the switch closed
timePushed = millis();
}
//******************
//switch has been released
else
{
//calculate the time the switch was closed
timePushed = millis() - timePushed;
if (timePushed < 500)
{
buttonPressCount++;
if ( buttonPressCount == MINBTNCOUNT)
{
buttonPressCount = MAXBTNCOUNT;
}
if ( buttonPressCount > MAXBTNCOUNT)
{
buttonPressCount = 1;
}
Serial.print("button count: ");
Serial.println(buttonPressCount);
}
}
}
}
void buttonPress2 ()
{
byte currentButtonState2 = digitalRead (buttonPin2);
if (lastButtonState2 != currentButtonState2) {
lastButtonState2 = currentButtonState2;
delay (35); // debounce
//******************
//has the switch been pushed ?
if (currentButtonState2 == PUSHED2)
{
//record the time the switch closed
timePushed2 = millis();
}
//******************
//switch has been released
else
{
//calculate the time the switch was closed
timePushed2 = millis() - timePushed2;
if (timePushed2 < 500)
{
buttonPressCount--;
if ( buttonPressCount == MINBTNCOUNT)
{
buttonPressCount = MAXBTNCOUNT;
}
if ( buttonPressCount > MAXBTNCOUNT)
{
buttonPressCount = 1;
}
if ( buttonPressCount == 255)
{
buttonPressCount = 1;
}
Serial.print("button count: ");
Serial.println(buttonPressCount);
}
}
}
}
the above code is working for counting up and down within a range.
I have tried to add another function for toggling the LEDS based on a counter and based on the ledOnTimearray[]
Here is my failed attempting:
void ledToggle()
{
for (int i = 0; i < MAXBTNCOUNT; i++)
{
if (counter != lstcounter)
{
Serial.print("counter:");
Serial.println(counter);
lstcounter = counter;
if (millis() - timeButtonPressed <= ledOnTime[i])
{
Serial.print(ledOnTime[i]);
digitalWrite(ledPins[i], HIGH);
}
}
if (millis() > timeButtonPressed + ledOnTime[i] || counter != lstcounter)
{
digitalWrite(ledPins[i], LOW);
}
}
}
It is for representing when a specific action is happening ( a track that is playing)
if led 1 is on I know track 1 is playing
if led 2 is on I know track 2 is playing.
counter is for iterate between tracks.
if counter == 1 track 1 is playing and led 1 should be on for the length of the track or until the button is pressed again and in that case the led will be off and a new led will be on indicate the new track .
My recommendation is to build some objects, like for the button, timing and Leds.
Some tasks take care about these objects and generates the needed output.
Classes aren´t needed, some structured arrays only.
I have already have the function for the button that made the counting as I need.
I also manage to turn on led based on counter for the length of the track.
When I tried to make it work with more then 1 variable (counter == 2) it was not working.
#include <wavTrigger.h>
#include <AltSoftSerial.h> // Arduino build environment requires this
// WAV Trigger object //
wavTrigger wTrig;
//time translating//
#define sec * 1000
#define min * 60000
#define ms * 1
// Track Lengths //
const unsigned long trackLength[] = {19 sec, 44 sec, 9 sec, 7 sec, 33 sec};
//Button//
uint8_t buttonPin = 2; // uint8_t is an unsigned (positive) 8-bit integer. Giving the compiler this detail rather than a generic 'byte' helps it treat it as you would expect, resulting in Serial.print not needing that 'DEC' argument.
uint8_t counter = 0;// Note an uint8_t stores a number from 0-255, so after 255 the counter will go back to 0 again. If you want to store a larger integer, use uint16_t (0-65535), uint32_t (0-4294967295), or even uint64_t (0-18446744073709551615).
uint8_t lstcounter = 0;
uint8_t PUSHED = 0;
const uint8_t MINBTNCOUNT = 0;
const uint8_t MAXBTNCOUNT = 4; //num of tracks
unsigned long timePushed = 0;
uint8_t currentButtonState = HIGH;
uint8_t lastButtonState = HIGH;
uint32_t millisTimePress = 0; // unsigned longs are uint32_t, an unsigned 32 bit integer.
////Leds/////
const int ledPins[] = {4, 5, 6, 7, 8}; // array of leds pins
const int numOfLeds = (sizeof(ledPins) / sizeof(ledPins[0])); // size of Leds
unsigned long timeButtonPressed = 0;
uint32_t currentMillis;
int gNumTracks; // Number of tracks on SD card
char gWTrigVersion[VERSION_STRING_LEN]; // WAV Trigger version string
void setup() {
Serial.begin(115200);
pinMode(buttonPin, INPUT_PULLUP);
// setting up the digital pins for the leds to be an output //
for (int j = 0; j < numOfLeds; j++)
{
pinMode(ledPins[j], OUTPUT);
}
delay(1000);
// WAV Trigger startup at 57600
wTrig.start();
delay(10);
// Send a stop-all command and reset the sample-rate offset, in case we have
// reset while the WAV Trigger was already playing.
wTrig.stopAllTracks();
wTrig.samplerateOffset(0);
wTrig.masterGain(-6); // Reset the master gain to 0dB
// Enable track reporting from the WAV Trigger
wTrig.setReporting(true);
// Allow time for the WAV Trigger to respond with the version string and
// number of tracks.
delay(100);
// If bi-directional communication is wired up, then we should by now be able
// to fetch the version string and number of tracks on the SD card.
if (wTrig.getVersion(gWTrigVersion, VERSION_STRING_LEN)) {
Serial.print(gWTrigVersion);
Serial.print("\n");
delay(1000);
gNumTracks = wTrig.getNumTracks();
Serial.print("Number of tracks = ");
Serial.print(gNumTracks);
Serial.print("\n");
}
else
Serial.print("WAV Trigger response not available");
}
void loop() {
buttonPress ();
isPlaying1(); // for track 1
isPlaying2(); // for track 2
wTrig.update();
}
void buttonPress ()
{
byte currentButtonState = digitalRead (buttonPin);
if (lastButtonState != currentButtonState) {
lastButtonState = currentButtonState;
delay (35); // debounce
//******************
//has the switch been pushed ?
if (currentButtonState == PUSHED)
{
//record the time the switch closed
timePushed = millis();
}
//******************
//switch has been released
else
{
//calculate the time the switch was closed
timePushed = millis() - timePushed;
timeButtonPressed = millis();
Serial.print("timeButtonPressed:");
Serial.println(timeButtonPressed);
if (timePushed < 500)
{
counter++;
if ( counter == MINBTNCOUNT)
{
counter = MAXBTNCOUNT;
}
if ( counter == 5)
{
counter = 1;
}
// Serial.print("button count: ");
// Serial.println(counter);
}
else if (timePushed > 600)
{
counter--;
// Serial.println(timeButtonPressed );
if ( counter == MINBTNCOUNT)
{
counter = MAXBTNCOUNT;
}
if ( counter > MAXBTNCOUNT )
{
counter = MINBTNCOUNT;
}
}
}
}
}
void isPlaying1()
{
if (counter != lstcounter)
{
Serial.print("counter:");
Serial.println(counter);
lstcounter = counter;
// Serial.print("millis: ");
// Serial.print(millis());
if (millis() - timeButtonPressed <= trackLength[0])
{
Serial.println(trackLength[0]);
digitalWrite(ledPins[0], HIGH);
wTrig.trackGain(1, -40);
wTrig.trackPlaySolo(1);
wTrig.trackFade(1, -6, 3000, false);
}
}
if (millis() > timeButtonPressed + trackLength[0] || counter != 1 )
{
digitalWrite(ledPins[0], LOW);
}
}
void isPlaying2()
{
if (counter != lstcounter)
{
Serial.print("counter:");
Serial.println(counter);
lstcounter = counter;
// Serial.print("millis: ");
// Serial.print(millis());
if (millis() - timeButtonPressed <= trackLength[1])
{
Serial.println(trackLength[1]);
digitalWrite(ledPins[1], HIGH);
wTrig.trackGain(2, -40);
wTrig.trackPlaySolo(2);
wTrig.trackFade(2, -6, 3000, false);
}
}
if (millis() > timeButtonPressed + trackLength[1] || counter != 2 )
{
digitalWrite(ledPins[1], LOW);
}
}
when counter == 2 I'm expecting it to print the time of track 2 but it printing the time of the first track (19,000 ms) I am thinking that this where the mistake is but can't fixed it
Using 'if else' instead of just 'if', for one thing. 'counter' can only have one value at a time, if it equals 1 for example, you don't need to test it to see if it's 2.
Or follow the advice of reply #9 and put the LED states in an array, and index the array with the counter.
Just as a comment on style, identifiers beginning with 'is..' like 'isPlaying' are usually advertising that they refer to a logical value (true/false) because it 'is' or 'isn't'. Functions with names like that usually don't affect anything, they only test the state of something.
@hk_jh it might be better to keep all this on one thread.
From your other thread, I had been writing but sorta gave up, I had this, never posted
Tuning in late…
You write
if (counter == 1) { led 1 is on for 10 seconds, all other led are off }
if (counter == 2) {led 2 is on for 20 seconds, all other led are off }
if (counter == 3) {led 3 is on for 30 seconds, all other led are off }
but that leaves many questions. Maybe you have answered them.
Would this be closer?
if the button gets pressed
stop any song that is playing and extinguish his LED
advance counter, if it gets to 3 set it back to 0
start playing track number counter
light up his LED
set up a timer
if the track playing finishes (timer runs out)
extinguish his LED
You were slogging it out with @Railroader over there.
Because English is not my first language I have hard time to find the words to explain exactly what I have in mind...
edit: the final code I have managed too write is working but very much not efficient . It got multiple repetition of code and is for playing only 4 tracks. If I would like to add more track the code will continue to increase in size.
I'll be happy to se more efficant code
Your English is better than my <insert any language here>.
But words are always going to come in second or worse when describing a system like this. @Railroader didn't, but often calls it word salad. It is hard to read a block of text and come away with a good idea of what you need.
Flowcharts can be useful.
Pseudocode, as I wrote, can be useful. It is more than words, less than real code. It forces you to think like it is coding, but relieves you of pesky details.
So you are saying that my pseudocode does what you want? From what I have seen so far here, you should be able to use the pseudocode to write the actual C/C++.
I'll try again without thewavTrigger library as at the end is only another line of code to play the track. The idea of the code could be without it for the sake of writing:
#define NUMTRACKS 4;
//time translating//
#define sec * 1000
#define min * 60000
#define ms * 1
// Track Lengths //
const unsigned long trackLength[] = {19 sec, 44.1 sec, 20 sec, 8 sec , 33 sec};
////Leds/////
const int ledPins[] = {4, 5, 6, 7, 8}; // array of leds pins
const int numOfLeds = (sizeof(ledPins) / sizeof(ledPins[0])); // size of Leds
//Button//
uint8_t buttonPin = 2;
uint8_t counter = 0;
uint8_t lstcounter = 0;
uint8_t PUSHED = 0;
const uint8_t MINBTNCOUNT = 0;
const uint8_t MAXBTNCOUNT = NUMTRACKS;
unsigned long timePushed = 0;
uint8_t currentButtonState = HIGH;
uint8_t lastButtonState = HIGH;
uint32_t millisTimePress = 0; //
unsigned long timeButtonPressed = 0;
void setup() {
Serial.begin(115200);
pinMode(buttonPin, INPUT_PULLUP);
// setting up the digital pins for the leds to be an output //
for (int i = 0; i < numOfLeds; i++)
{
pinMode(ledPins[i], OUTPUT);
}
}
void loop()
{
buttonPress ();
runSequence();
}
void buttonPress ()
{
byte currentButtonState = digitalRead (buttonPin);
if (lastButtonState != currentButtonState) {
lastButtonState = currentButtonState;
delay (35); // debounce
//******************
//has the switch been pushed ?
if (currentButtonState == PUSHED)
{
//record the time the switch closed
timePushed = millis();
}
//******************
//switch has been released
else
{
//calculate the time the switch was closed
timePushed = millis() - timePushed;
timeButtonPressed = millis();
Serial.println();
Serial.print("timeButtonPressed:");
Serial.println(timeButtonPressed);
if (timePushed < 500)
{
counter++;
if ( counter == MINBTNCOUNT)
{
counter = MAXBTNCOUNT;
}
if ( counter == 5)
{
counter = 1;
}
}
else if (timePushed > 500)
{
counter--;
// Serial.println(timeButtonPressed );
if ( counter == MINBTNCOUNT)
{
counter = MAXBTNCOUNT;
}
if ( counter > MAXBTNCOUNT )
{
counter = MINBTNCOUNT;
}
}
}
}
}
//track playing/ LED indications //
void runSequence()
{
for (int i = 0; i < MAXBTNCOUNT; i++)
{
if (counter != lstcounter) //check if there is a new value of counter(button state was changed)
{
Serial.print("counter:");
Serial.println(counter);
lstcounter = counter;
if (millis() - timeButtonPressed <= trackLength[i])
{
Serial.print("track ");
Serial.print(counter);
Serial.print("length: ");
Serial.println(trackLength[i]);
digitalWrite(ledPins[i], HIGH);
}
}
if (millis() > timeButtonPressed + trackLength[i])
{
digitalWrite(ledPins[i], LOW);
}
}
}
When I first press the button the serial is printing:
Which is exactly what I am expecting and indeed the LED os turned off after 19 seconds.
When I press the button again it print (marked in green):
track length should be 44100 but it printed 19000. I think I have found the first mistake.