why does this sketch loop, how do i stop it?

I found this on a board. it isn't mine. I am trying to learn and understand how writing sketches works. I am "show me" and i'll go play with it till i "get it". it is "almost" what i want to do but i need some explanation. can someone tell me "why" this track loops? and can you tell me how to STOP it? the goal is to loop 50 tracks, with a 25 second delay between each PLAY. i have figured out a lot of ways it "won't work". the components are a bare atmega 328 and an adafruit fx sound board.

so, Why does it LOOP. And how do i make it play once for starters?????

THANX! the sketch is as follows:

/*
Menu driven control of a sound board over UART.
Commands for playing by # or by name (full 11-char name)
Hard reset and List files (when not playing audio)
Vol + and - (only when not playing audio)
Pause, unpause, quit playing (when playing audio)
Current play time, and bytes remaining & total bytes (when playing audio)

Connect UG to ground to have the sound board boot into UART mode
*/

uint8_t TRACK_0 = 0;

int PIN_ACT = 12;
int act_val = 0;

#include <SoftwareSerial.h>
#include "Adafruit_Soundboard.h"

// Choose any two pins that can be used with SoftwareSerial to RX & TX
#define SFX_TX 7
#define SFX_RX 8

// Connect to the RST pin on the Sound Board
#define SFX_RST 4

// You can also monitor the ACT pin for when audio is playing!

// we'll be using software serial
SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX);

// pass the software serial to Adafruit_soundboard, the second
// argument is the debug port (not used really) and the third
// arg is the reset pin
Adafruit_Soundboard sfx = Adafruit_Soundboard(&ss, NULL, SFX_RST);
// can also try hardware serial with
// Adafruit_Soundboard sfx = Adafruit_Soundboard(&Serial1, NULL, SFX_RST);

void setup() {

pinMode( PIN_ACT, INPUT_PULLUP );

Serial.begin(115200);
Serial.println("Adafruit Sound Board!");

// softwareserial at 9600 baud
ss.begin(9600);
// can also do Serial1.begin(9600)

if (!sfx.reset()) {
Serial.println("Not found");
while (1);
}
Serial.println("SFX board found");
}

void loop() {
act_val = digitalRead(PIN_ACT);
if ( act_val == HIGH ) {
sfx.playTrack(TRACK_0);

}
}

Please use code tags (</> button on the toolbar) when you post code or warning/error messages. The reason is that the forum software can interpret parts of your code as markup, leading to confusion, wasted time, and a reduced chance for you to get help with your problem. This will also make it easier to read your code and to copy it to the IDE or editor. If your browser doesn't show the posting toolbar then you can just manually add the code tags:
[code]``[color=blue]// your code is here[/color]``[/code]
Using code tags and other important information is explained in the How to use this forum post. Please read it.

Please always do a Tools > Auto Format on your code before posting it. This will make it easier for you to spot bugs and make it easier for us to read. If you're using the Arduino Web Editor you will not have access to this useful tool but it's still unacceptable to post poorly formatted code. I recommend you to use the standard IDE instead.

Any code in the setup function will be run once on start up. Any code in the loop function will be run over and over again forever.

I am "show me" and i'll go play with it till i "get it". i

That works for lots of things but it almost never does with coding. This is one area where you really have to be willing to do a little reading and learning. Everything is so exacting and you might be one little thing off and it just won't work. And the things that you miss often aren't intuitive enough for you to ever find them by just playing around. If you want to be able to do this kind of stuff then you're going to have to do at least a little learning the traditional way.

Even the pros at least go read the basic docs on a new API before they just dive in. It's really hard to know what you might be missing if you don't.

so, Why does it LOOP. And how do i make it play once for starters?????

Because you have the sfx.playTrack function call in the "loop" subroutine. Any code in that subroutine repeats forever.

This should play track zero once at start if pin 12 is high.

/* 
  Menu driven control of a sound board over UART.
  Commands for playing by # or by name (full 11-char name)
  Hard reset and List files (when not playing audio)
  Vol + and - (only when not playing audio)
  Pause, unpause, quit playing (when playing audio)
  Current play time, and bytes remaining & total bytes (when playing audio)

  Connect UG to ground to have the sound board boot into UART mode
*/

uint8_t TRACK_0 = 0;


int PIN_ACT = 12;
int act_val = 0;

#include <SoftwareSerial.h>
#include "Adafruit_Soundboard.h"


// Choose any two pins that can be used with SoftwareSerial to RX & TX
#define SFX_TX 7
#define SFX_RX 8

// Connect to the RST pin on the Sound Board
#define SFX_RST 4

// You can also monitor the ACT pin for when audio is playing!

// we'll be using software serial
SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX);

// pass the software serial to Adafruit_soundboard, the second
// argument is the debug port (not used really) and the third 
// arg is the reset pin
Adafruit_Soundboard sfx = Adafruit_Soundboard(&ss, NULL, SFX_RST);
// can also try hardware serial with
// Adafruit_Soundboard sfx = Adafruit_Soundboard(&Serial1, NULL, SFX_RST);

void setup() {

 pinMode( PIN_ACT, INPUT_PULLUP );
  
  Serial.begin(115200);
  Serial.println("Adafruit Sound Board!");
  
  // softwareserial at 9600 baud
  ss.begin(9600);
  // can also do Serial1.begin(9600)

  if (!sfx.reset()) {
    Serial.println("Not found");
    while (1);
  }
  Serial.println("SFX board found");

  act_val = digitalRead(PIN_ACT);
  if ( act_val == HIGH ) {
    sfx.playTrack(TRACK_0);
    }
}

void loop() {
}

Thanks guys, points taken, suggestions read and understood. Not to sound argumentative, but I do read a lot, watch a lot of youtubers and study and take notes, duplicate if possible. What I am learning is there are many different ways to accomplish the same thing. I have also found in reading through the forums, some people offer misinformation. not to say they don't mean well or that I know better. But, there are "parts" of this that I understand fairly well considering how long I have been at it. Serial Communication however is new to me. As far as show me and I'll figure it out. In my case it works well. There are many examples out there but unfortunately not commented out well enough for me to understand them. They are also not specific to what I would like to accomplish.

As per the example provided (Thank you) it "shows me" what to do. I have 2 options now, both the loop and the play it once for the sketch I am creating. I'm sure there will be other questions that come up, but for now I have something to work with and figure out. I do appreciate everyone's input and will make it a point to abide by the forum rules.

Have a great weekend, Many thanks

Fredric58:
so, Why does it LOOP.

As long as that pin is HIGH (and if you do nothing with it will be as you have set INPUT_PULLUP), the if statement is true, and it plays on and on and on.

And how do i make it play once for starters?????

Place that line in setup() and keep your loop() empty. Setup() is run once and only once on startup.

Fredric58:
Not to sound argumentative, but I do read a lot, watch a lot of youtubers and study and take notes, duplicate if possible.

YouTube is great for fun ideas, but a terrible place to really learn. Most of the people who post there don't know enough to write technical documentation. So if you go to the technical documentation, there is a kind of natural weeding out process going on there. If you learn to learn from the source, it's kind of a teach a man to fish vs. give a man a fish thing. On YouTube, you basically have a menu of fish. Often bottom feeders.

yes some of the tubers are flakey as well as some of the advice in this forum. there are a few on yt that are pretty good though. check out a guy named kevin darrah and see if we are in agreement. and advise me if time spent studying his projects is worth the time spent. his low power mega 328 is pretty cool.

if I had time I would go to school to learn this as it is rather difficult to teach ones self. school isn't possible. the reading is from this site, though understanding much of it is difficult. so I just piece together stuff to accomplish the task then ask for recommendations to make it simpler or even stream line it. with each bit of advice I get here it turns usually into another tool for me to work with.

I will be using kevins sleep tutorial in my project. it's been stated on many occasions that when putting a 328 into a deep sleep. to make the commands as short and simple as possible, to NOT use delays. what is left unclear is the delay part. is it meant don't use it in the sleep command or avoid using it in the sketch as well?

I would assume it means in the sleep command, but it's not clarified in any of the instructionals.

The goal with low power is to spend the most possible time sleeping. When you use delay the microcontroller is using the normal amount of power but it's doing nothing useful with that power. Therefore for any significant delay it would be much better to just put the microcontroller to sleep. For very short delays it's not worth it as it takes some time to wake up.

to clarify, I have read it isn't a good idea to use delay in a sleep enable command. it appears it is ok to use it in the actual sketch. the project I am working on doesn't do any thing 12 hours a day. it will wake up at 9:00 pm, then return to sleep mode at 5 or 6:00 am. I have it down to 2-3uA in sleep mode. I'm using a bare atmega 328p-pu with a 16 MHz crystal, 2 22uf caps and a 10k res. on reg.5v. I know it could be lower at 3.3v with 8 MHz but 5v is fine for this test.

which brings me to a question I haven't found an answer for. I'm using a RTC DS3132 for the interrupt. since it is a "MATCHTIME" to interrupt. if there is no power to the 328 and I power it up at say 3:00pm. will I have to wait for a "MATCHTIME" event to occur before it begins to work?

in other words, if if I turn it on at 3:00pm from zero power, will it/should it know it is supposed to be asleep till 9:00pm?

that make sense?

Fredric58:
yes some of the tubers are flakey as well as some of the advice in this forum.

No the advice here is very sound. If flakey advice is given it is quickly stamped on.

will I have to wait for a "MATCHTIME" event to occur before it begins to work?

Yes. Providing the RTC was running off a back up battery. If it is not then the MATCHTIME time will not be set at turn on time.

Fredric58:
I know it could be lower at 3.3v with 8 MHz but 5v is fine for this test.

Not necessarily. If the microcontroller is only awake when something actually needs to be done and you can get that thing done more quickly and get right back to sleep by running at 16 MHz then it will usually end up using less total power at the higher clock speed. That doesn't account for possible power supply efficiency differences between the two voltage levels. If the microcontroller is spending relatively long periods of time awake doing nothing then running faster is not helpful.

Grumpy_Mike:
No the advice here is very sound. If flakey advice is given it is quickly stamped on.

That was my thought when I read that, too.

ok ok, not the advice, but some of the recommendations in the threads, more than likely from noobies I would imagine. that's when people ask "how do I do X?" there's usually a handful of suggestions, and some I know aren't the correct way to accomplish the task. or should I say the best way. not claiming fame but I do know some things.

yes there will be a back up battery on the RTC. and per grumpy. I haven't started on the sleep mode portion yet. no one round here stocks the 1220 batteries so I had to order them on line.

so, if it has to wait for a time match will the sketch run till one of the interrupts is eventually reached? that will pose a problem, only on the first day. but it is still a problem. just thinking ahead.

do you think it could be set up in a way that: "if" it is between 6:00am and 9:00pm sleep, "if not" wake?

also, I understand the WDT is inaccurate and has to be looped for anything over 8 seconds. that it consumes more power as well. I need (2) timed events. the first is to initially turn the project on and the 2nd is to sleep between tracks. in the loop where there is a delay (it's 5 seconds right now but will be 25 sec in the final version) I would like to save that power. I could come close with the WDT (24 sec) which would be fine. timing isn't super critical. or would it be recommended to use (2) RTC's? I will post the code next, I'm in the quick reply window

problem solved, what do you think. use (2) tactile buttons, 1 white, 1 black. both interrupts. if it's turned on during the day, press and hold white (day) 10 sec. enable sleep. turn it on at night press hold black enable wake up. then it should pick up the time match when it arrives? yes? no?

pondering something else. would it be possible to pre define the tracks and in the loop just state "play next track"? there will be a lot of them.

do you think it could be set up in a way that: "if" it is between 6:00am and 9:00pm sleep, "if not" wake?

Well it is more like:-
"if" it is between 6:00am and 9:00pm sleep, "if not" carry on because it is already running.

would it be possible to pre define the tracks and in the loop just state "play next track"?

Yes, hold the track names in an array and simply increment the array index.

when people ask "how do I do X?" there's usually a handful of suggestions, and some I know aren't the correct way to accomplish the task

When giving the question "how do I do X?" to N engineers there are always at least N+1 strongly held beliefs of how to do it.

Grumpy_Mike:
When giving the question "how do I do X?" to N engineers there are always at least N+1 strongly held beliefs of how to do it.

can you name 25 ways to get to the end or your street ?
hopping counts as 1
as does using a helocopter
just because there are a dozen ways to get to the same result, does not mean any are wrong.
if you have 10 songs you use simple if() statements and a counter to select which song to play.
you can use an array and get the exact same result.
you can put each song in it's own loop
song1(){
//song 1 stuff here
}
song2(){
//song 2 stuff here
}
loop()
song1();
song2();
song3();
how you get to the results are a combinatioin of may factors.
what you know that YOU can do is one
what you copied from instructables is another
what a fellow noob copied from youtube and altered, then posted is yet another.
I can tell you without reservation that at the end of the day, if your sketch works exactly the way you want, then, it is not done wrong.

thanks for the input. I guess as in commenting as well as code, one must be explicate. what I was referring to for example was. if some one asks "what is the best way to put to sleep and interrupt that saves the most power?

and someone has the example "use power down with the WDT" vs a RTC." without mentioning the other 3 or 4 things that can have a huge impact on power consumption. Sure, it'll work, and if you're happy at the end of the day. that's great!

I fully agree with you in that there are at least 10 ways to skin a cat. some are just better than others as judged by the results and would almost bet it is the same for coding?

thanks again, going to go research arrays.