RTC and POWER_DOWN ADC OFF BOD OFF

I thought I had posted this already but can't find it any where. I have read Gammons POWER_DOWN and WAKE UP and have a fairly good understanding of it for someone new to Arduinos. I have a couple questions that I haven't found answers for through lengthy searches on this forum, the web and youtube.

Components are a DS3231 RTC, a bare/breadboard ATMega 328P-PU and an Adafruit FX Sound module.

I can recreate a (if HH ==X) POWER_DOWN and (if HH == Y) WAKE. At given times. Example: turn on a LED at 7:00 pm and turn it off at 4 am. not a big deal.

I can also POWER_DOWN for 25 seconds, activate the sound board (play a tune) and POWER_DOWN over and over again. non stop

What I am having trouble finding an answer to is this. Is it possible, using (1) RTC. to put this 328 in POWER_DOWN mode from say 6:00 am to 6:00 pm. It doesn't need to do anything for half a day.

at 6:00pm I would like it to WAKE UP and run a simple loop. The catch is it has to also power down inside the loop. So, 25 seconds POWER_DOWN, wake up for (5) seconds play a track from the FX sound board, POWER_DOWN and repeat.

It needs to run the loop till 6:00 am. THEN it needs to POWER_DOWN/sleep the rest of the day.

An important part of the question to take into consideration is: you never know what time the device will be turned on. It could be while it is supposed to be asleep, or it could be when it is supposed to be awake running the loop. There is however "the clock". is the Arduino smart enough to know which segment it is in?

Another important part of the question is: there are delays involved. so another question is: if the "go to sleep for the day" happens during a delay, is it possible it will be missed? OR, is there a way in which you can call. "IF" and leave a window of time in the event that the "go to sleep happens to land during one of those delays? like say between a 6:00 and 6:15 time stamp?

these are as straight forward as I can word them and would think they are either YES or NO answers. I read some where, ask a good question, get a good answer.

NO, I don't have code to provide you or an explanation of my project because at this point I don't know if what I would like to accomplish is even possible and the reason why I have tried to articulate the questions in a relatively simple manner. I am simply looking for feedback as to whether or not I am trying to accomplish something that the Arduino is capable or incapable of doing. The WDT is not an option. It requires a few extra mA's.

any input is appreciated, considering the complexity and my lack of skill. hope everyone has a Merry Christmas.

Thanks, Fred

you can use an interrupt from the RTC to wake up the Arduino, e.g.
http://www.instructables.com/id/Arduino-Sleep-and-Wakeup-Test-With-DS3231-RTC/

to maintain track of where you are in the sequence of events in the system use a state machine

Thank you for the direction Horace. Looks like I will be studying state machine today

WOW! I think that is the best direction I have received of all time. I spent about 8 hours studying state machine today and it is amazing. it simplifies every thing. I do appreciate that. There are only 3 states.

Sleep, Wake and Play. Writing it will still be a challenge but it REALLY opened up a door for me to limitless possibilities. It's just amazing!

Thanks Horace.

it may be useful to draw a state machine diagram which shows the control moves from state to state

you then map this into code

I have seen a lot of that and even drawn it out. I have determined that I will probably have (4) states with some variables. this is "kinda" an outline. A starting point.

STATES:

A. CALCULATE TIME: // if between 5am and 7 pm move to B, if not, move to C

B. SLEEP MODE: //POWER_DOWN

C. WAKE MODE: //AWAKE. move to D

D. PLAY MODE: // While AWAKE=PLAY//check time, at end time move to back to B.

the part that I can't wrap my head around is it's going to play music when it is AWAKE. HOWEVER I need to put it back to sleep IN BETWEEN songs IN BETWEEN 7PM and 5 AM. when it is in (C). so (C) is really awake play sleep awake play sleep.

SO maybe? (C) should/could actually be WAKE PLAY SLEEP MODE:? and remove D? then just have C keep checking time till it is time to go back to B.

Am I on the right track? This is my first go at this....

Thanks

A is not a state you are just checking the time - it controls the change of state
In C when you have finished a song should you move to D doze and after a time back to C?

ok, I see
so I want it to start "ON" so I know it's working. instead of a LED

I'll put a STATE 1 is PREVIEW ALL TRACKS//plays all tracks with 1 sec between. they're short.

Then, CALCULATE TIME// are we supposed to be at work or asleep and change STATE.

gets me to STATE 2 or STATE 3

STATE 2: POWER_DOWN// watch for interrupt till time to wake (7:00 pm). change to STATE 3

STATE 3: WAKE// play next track (array?) //change to STATE 2// get seconds, count (25) seconds, interrupt, LOOP STATE 3, while watching clock for long sleep (5am to 7pm)

enum MusicBoxState {

PREVIEW, SLEEP, WAKE }

maybe?

an enum doesn't dictate the order of execution... that is controlled by the logic of your program in which the contents of it are referenced.

You might as well have

enum MusicBoxState {

WAKE, SLEEP, PREVIEW}

It makes no difference later on.

explain?

the enum defines the possible states it is up to your code to decide how to move between states

assume a simple alarm clock . when alarm goes off it plays a track , when track is over it dozes for 5 minutes then plays the next track
outline code may look like

enum MusicBoxState {  SLEEP, WAKE, PLAY, DOZE } state;

void loop()
 {
 switch (state)     // switch on current state
  {
  case SLEEP: if(time == wakeTime) // if time to wake up
                 state = WAKE; 
              break; 
   case WAKE: play(track);     // function to play a track
              state=PLAY;
              break;
   case PLAY: if(!playing())   // if track finished doze
                 state=DOZE;  
              break;
   case DOZE: if(dozeTimeOver)  // if doze time over play next track
                  state=WAKE;
              break;
    }
}

assuming a music player has two functions play() which starts playing a track and playing() which checks if a track is playing or finished
DOZE needs some test to exit the WAKE PLAY DOZE cycle and return to SLEEP

I revisited this last night and determined that the preview was not a state. and was thinking either a sleep1 sleep2 state, a wake state, and a play, don't play state. but as far a managing them, the example given makes much more sense.

the sound module operation is based on an "if", that is "if" the act pin is set high, then the next command is sfx play TRACK 1. how ever I want to simplify play track 1, play track 2... and use an array and simply set it up to Play next track as there might be 6, 20, 30 tracks loaded at any given time. the sound module is pretty simple and uses rx and tc for commands. I have that part figure out but only with a WDT.

because the atmega will be turning on the power of the sound board I have discovered that it needs at the least 500ms to stabilize before sending it any command. which I simulate at present with an LED that will be later replaced with an NPN transistor used as a switch. which will eliminate power consumption of the sound board while in sleep mode.

I have learned to use the RTC to turn something on or off at a given time using (this isn't code just explaining) the if HH == hour on-ON and vice vs , a match hour.

so let me pose this question. the mega reads the clock every second, or by hour, or day. it can be many different MATCH TIME definitions. since I have (2) separate requests/interrupts. the first being HOURS, SLEEP at 5 am and WAKE at 7 pm. will it be possible during WAKE to do a GET SECONDS like in the blink with out delay wherein it (I'm at work now without my notes) so I hope this some sense. it's like millis =currentmillis where it captures a second counts 25 of them for the sleep time and then continues on?

thank you.

I am going to start building upon the given example in the mean time by trying to define the states and post it for evaluation when completed.

RTC chips usualy have an alarm function
could you put the ardino to sleep and get the RTC to wake it up with an interrupt at the alarm time

yes, the ds3231 has 2 alarms if I recall correctly. I figure if I can turn a light on at a given hour and turn it off at a given hour I should be able to replace that with power down/wake interrupt. there are 2 things that stump me though.

the first is, if I turn a light on a 7pm and off at 5am, that works if the arduino is turned on before 7pm. if I turn the arduino on at 8pm it won't know what state to be in till the next alarm. so nothing happens till a day later. I haven't figured out a way to say "if it is 7pm or later and or 5am or earlier" WAKE. else SLEEP

with timers it's easier because I can specify the start time plus additional time and bang. this poses a challenge because the WDT has an 8 sec limit and it is sloppy and it would have to be looped 3 times and that I would consider sloppy too. I think the RTC would be more efficient but have yet to determine whether I can use a match hour alarm and a get seconds because of going between wake and sleep modes.

much to learn